- Declare the local variable as close to where it is used and remove un-necessary once
- Just return it. Don’t store
- Remove commented code
- Remove functions and variables which you do not use.
- Variable argument lengths
- Default Arguments
- Use annotations/decorators
- Remove duplicates
- Single line boolean evaluation
- Think in terms of Streams
- Create and use base classes
Declare the local variable as close to where it is used and remove un-necessary once
Local variables declared at some different place makes it harder to read the code.
Below are the variations of aRandomFunction which does a bunch of operations (skipped by dots) and on completion returns “Hello” along with the date.
The local variables names and date are declared on top of the functions.
The first usage of the functions are somewhere between the function and the last usage is in the return statement.
Here name and date variables are moved to where they are first used.
Let’s say after moving we realize that we do not use the variables between the code, we just use it during return.
So we should move it near the return statement:
Just return it. Don’t store
Continuing from the previous example:
Storing in a variable is un-necessary is it is never used.
Rather than storing “hello” in name and a new date in date, we should just return it.
Remove commented code
In case you do need to refer to the exact code you can always check it in your version control.
Remove functions and variables which you do not use.
Variable argument lengths
Python: *args, **kwargs (more than just variable-length argument)
Java also has an implementation for variable length arguments but they are not as elegant as Python implementation. Therefore, a list as an argument might be better suited.
Python and Typescript both support default function arguments.
While not officially supported in Java, one can work around the builder pattern to get similar functionality.
Annotations extend the functionality of your function dynamically and reduce the size of the code dramatically.
In python, these are called decorators.
Python 3.7+ also has @ dataclass **annotation which auto-generates constructor, **str and repr.
[functools](https://docs.python.org/2/library/functools.html#module-functools)— Higher-order functions and operations on a callable object
Spring Boot (Java)
![Source: Spring Annotations Cheat Sheet
Java: For JPA
No need to write @Column over your entity’s variables. By default, camelCase is substituted with snake_case.
lookupId => lookup_id
You can change these using naming strategies.
Java: Map using Mapper. Don’t create your own logic.
There are many mapping frameworks in Java that can make the task of converting one object to another much much easier. This can be especially helpful when you want to convert your @Entity to a DTO object.
Java: Project Lombok to avoid boilerplate
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
@Getter and @Setter
The good thing is that it is present is SpringInitializer. Just click the Project Lombok option.
With this, the size of your java code will reduce dramatically.
Linters will provide you a list of duplicate codes. Shove it into a function/method.
Use existing/inbuilt methods rather than new once
This goes back to not inventing new algorithms. If something is already made, don’t make it again. Reuse it. (Link — Clean Code: Know thy complexities)
Probably a bad example #1 of reuse:
Below is a very complex function. One of them works with List and other with an array but that is the only difference in implementation.
The bad approach is creating the same logic to work with different data structures.
A better approach is to have one main logic function and convert one data structure to another and then call the main one.
We can also take advantage of having the same name for both the functions which means less to remember.
Probably a bad example #2 of reuse:
This is similar to the above.
Here suppose you already have a complex function that works on a list of integers, and now you have to make a similar one to work on a single int.
Single line boolean evaluation
Think in terms of Streams
Streams make your code really really tiny and give much better performance. Streams do have a learning curve but are worth it.
(swap in a stream() for parallelStream() and you just went Super Saiyan 3)
Though the implementation of Java streams and having a single line list comprehension in Python are very different, they are similar in terms of style of code.
Create and use base classes
Base classes are an excellent way to avoid duplications. Make them as generic as possible.
Previous: Make database do the heavy lifting
Index: Tips on writing Clean Code