Java Clean Code - How to Write Clean Code in Java?

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Topics Covered

Clean code is code that is easy to understand and maintain. In short, clean coding is the way of writing code that is easily readable, testable, and less prone to errors.

Several principles should be considered while developing a software application. Some of these principles are SOLID, DRY, and KISS.

Apart from principles, certain properties, such as high cohesion and low coupling, documented code, proper naming, project structure, etc., lead to quality code.

What Is Clean Code in Java?

Steven C. McConnell, the author of Code Complete, Rapid Development, and Software Estimation who is cited as an expert in software engineering, once said

"Good code is its own best documentation" - Steve McConnell

what is clean code in java

Steve McConnell wanted the programmers to think before adding any comment in the code. He encouraged improving the code quality to such a level that comments are not required in the code at all. He supported the idea of documentation post-coding to make the code functionality even more clearer.

But What is a clean code? The code that is less prone to errors and easily readable, modifiable, scalable(in some cases), and maintainable by any developer (not just its programmer) is referred to as "Clean Code". Less prone to errors means that there will be very few chances of getting bugs in that code. Have you ever thought about Why writing clean code is so important? Let's find out in the next section.

Takeaway:

Clean Code is easily readable, maintainable, and less prone to errors.

Why do we need to care about Clean Code?

There can be multiple answers to this question, but we will choose the most suitable answer. We need to care about Clean Code because it eventually shows the programmer's capability of writing a well-maintainable piece of code that is easily understood by other developers who will work with that code.

In real life, when a programmer works on a codebase, there is a high chance that other programmers will also work on the same codebase at some point. Hence, the programmer needs to write clean code, as it will eventually be easier for other programmers to handle that code. More precisely, it will be easier to troubleshoot errors that can appear in the future.

Takeaway:

Writing clean code reflects a programmer's capability to write the code that makes their and other programmers' lives easier.

Characteristics of Clean Code

Let us discuss the characteristics of clean code.

  1. Simple: The code should be as simple as possible. Making a piece of code unnecessarily complex not only makes it hard to understand but also prone to errors.
  2. Maintainable: It should be maintainable in the long run as many different developers can work on that code. By the term maintainable, it is meant that the code can be easily modified without breaking it.
  3. Testable: It should be easily testable and less prone to errors. Clean code testing is intuitive and does not require manual intervention. Clean code encourages automated testing, as the code organization itself is very standard and supports automation.

These characteristics differentiate Clean Code from Bad Code. But What is a Bad Code? Are there any signs or characteristics of bad code? So yes, you need to be aware of several signs of bad code.

What are the signs of bad code (Unclean code)?

First of all, what is a Bad Code? There can not be any specific answer to this question, as the answer depends on the programmer's perspective. To be specific, any code that leads to a specific set of problems, in the long run, can be referred to as Bad Code. These problems can be:

  1. Hard to read code
  2. Unnecessarily complex
  3. Not easily testable
  4. Hard to modify

How to write Clean Code in Java?

So finally, it's time to learn how to write clean code in Java. Java is one of the most used programming languages, which has evolved immensely in the past few years. Many big tech firms use Java for their prominent operations.

The points mentioned below are extremely important to achieving clean coding in Java and other programming languages as well. So let us dig deeper:

1. Structure

Project Structure refers to the way of organizing different utilities of your projects such as source files, data, configurations, tests, etc.

Maintaining a sound project structure is necessary to reduce search time among files. In Java, there is no rule to follow a particular structure for your project, but it does not mean you should not. In fact, it is a good practice to follow a particular project structure.

Did you know?

A Java build tool is a command-line utility or program that automates the compiling process. In fact, processes like assembling and deploying the software are also automated using Java build tools. Build tools also help in package management(for project structure), dependency handling, etc. Some popular Java build tools are Apache Maven, SBT, Gradle, and Apache Ant with Ivy.

Even though you can follow your pattern, several Java build tools advise a specific structure for your project. One such build tool is Maven. Maven suggests some folders we should create and include in our project structure. So, let's have a look at the project structure that Maven suggests.

  • src/main/java: It contains the source files of your project. You can identify it as the sub-folder is main in this case.
  • src/main/resources: Contains the resource files of your project. You can identify it as the sub-folder is main in this case, also.
  • src/test/java: Contains the test source files of your project. In this case, you can identify it as the sub-folder is test.
  • src/test/resources: Contains the test resource files of your project. In this case, you can also identify it as the sub-folder is test.

As you can see, the files in this type of project structure are properly segregated as application and testing codes and resources. If not Maven, you can choose from other such project structures available for Java according to your requirements. Now we are going to see the second point, i.e. Naming.

2. Proper Naming

Any programming language has rules for creating and naming identifiers. Java also has such rules. While following the naming rules, one should also name the identifiers that show some meaning (that relates to the variable).

When we name something related to the content of a variable, the code becomes much more readable and understandable, which eventually helps maintain the code in the long run. In Java, we have to name variables, classes, methods, etc. Hence, we should always give them a name that relates to their functionality.

For example, If you want to create a variable for counting, name it 'counter' instead of 'c' or something similar.

You should always avoid naming variables with a single character like 'a', 'b', 'c', etc.

3. Source File Structure

The source file structure can contain many different types of elements. We can follow any available source file structure or create our own if needed and stick to it.

Normally, the elements placed in the source file are in the following order:

  • Package statement
  • Import statements
    • All static imports
    • All non-static imports
  • Exactly one top-level class
    • Class variables
    • Instance variables
    • Constructors
    • Methods

An example of a typical source file structure that is well-formed:

4. Code Formatting: Whitespaces and Indentation

This may look like the most obvious thing in this article, but it is often ignored. Whitespaces can help you make your code very readable. That is why it is advised to add whitespaces and indentation as this makes the code less prone to errors and easy to read and understand.

For example:

In this function, whitespaces and indentation are not taken care of.

While in this function, whitespaces and indentation are properly taken care of.

5. Method Parameters

We often create methods with parameters, but sometimes we add so many parameters to a single method that it leads to confusion. The idea here is simple: avoid adding more than three parameters if possible, as it can create unnecessary confusion for other developers or programmers who will deal with that code in the future. You can also go for refactoring if possible, as we have done in the example given below:

In Programming, Refactoring is a technique used for restructuring an existing code without modifying the external behavior of the code.

Example:

Explanation:

In the example above, we can create a class Employee_Details, and data such as awards, ctc, and experience can be its instance variables. Hence, instead of passing three variables separately, we can now send an object of Employee_Details class.

6. Avoid Hardcoding

In simple words, hardcoding is the practice of adding the raw data directly into the source code of a program wherever needed instead of using a variable to store the raw data and using that variable. Remember that heavy hard coding can cause serious maintainability problems in your project.

Example:

  • Let's say you have decided to use 404 as the error code in your project. Whenever an error occurs in a method, 404 is returned. Using this error code 404, the control flow is changed as numerous places.
  • Now, what happens when you need to use a new error code say -1. You have replace the raw value 404 with -1 at all the places where it is used.
  • This is very difficult and irritating when it comes to large projects. Instead we can simply use a constant ERROR_CODE and assign it the value 404 or -1. Now, this constant identifier can be used anywhere in the code.
  • If any change is required in the future, we need only change the ERROR_CODE constant identifier; otherwise, everything will work smoothly.

7. Code Comments

Many experienced programmers or developers recommend adding comments to your code so that you or any other developer can understand its functioning in the future. Commenting is also considered one of the best practices for making the code easily understandable. It has been observed that initially, some developers don't follow the commenting practice. Then, after some time, when they see that uncommented code, it becomes very difficult for them to understand it.

In Java, two kinds of comments are allowed: Documentation comments and Implementation comments. Let us see them in detail.

  • Documentation/JavaDoc Comments
    • Here, The target audience is the users of the codebase
    • The details added here are generally implementation-free and focus mostly on the specification purposes.
  • Implementation/Block Comments
    • Here, The target audience is the developers that work on the codebase
    • The details added here are generally specific to the implementation.

Using JavaDoc comments for most of the classes, interfaces, public and protected methods, is a good practice.

8. Logging

Logging is one of the most critical factors in clean coding. A well-logged code is easy to debug and can save a developer's work hours. One should always avoid excessive logging because it can lead to decreased performance.

9. SOLID

In the history of object-oriented software development, Robert C. Martin promoted the SOLID design principles. These principles are some of the best design principles in object-oriented software development. So, SOLID is a mnemonic acronym for the five principles given below:

  • Single Responsibility Principle
  • Open/Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Each of the above-mentioned principles has one goal: to improve the maintainability, reusability, and robustness of object-oriented applications. Let us see them one by one in brief.

  • Single Responsibility Principle: This principle states that, In Java, each interface, class, or method we define should be very specific, meaning it should have a single responsibility. Simply put, it should do only one task and do it well. The methods and classes become smaller and easily testable by consistently following this principle.

  • Open-Closed Principle: This principle states that our code should ideally be open to any kind of extension and closed for any modification. In simple words, our code should be easy to extend but good enough that no modification is required in our code.

  • Liskov Substitution Principle: It states that the objects of a superclass should be replaceable with the objects of its subclasses but without causing the application to break.

  • Interface Segregation Principle: Defined by Robert C., this principle aims to reduce the side effects from the code and frequency of required changes by splitting or dividing the software into many independent parts or interfaces.

  • Dependency Inversion Principle: According to this principle, classes should only depend on abstractions, not implementations. In simple words, High-level(complex) modules, which provide complex logic to your software, should be easily reusable. They should not be affected by the changes of low-level modules, which generally provide utility features.

10. DRY & KISS

DRY stands for "Don't Repeat Yourself". DRY emphasizes not repeating the same code again and again. Simply put, the main motive behind this principle is to make the code reusable. It says that every piece of knowledge must have a single authoritative presentation within a system and it must symbolise the idea/functionality it has presented.

KISS stands for "Keep It Simple, Stupid". As the words of this acronym suggest, this principle states that the code should be made as simple as possible. The key concept is that for a product to succeed, it must be easily understood and usable by everyone.

Example of Clean Code in Java

Now, as we have seen how to write clean code in Java, let's look at an example.

Explanation:

In the above-given example, we have created a public class named Employee (remember that we name the class with the first letter as capital) then we have created a private string variable called employeeName and a public method called getEmployeeName which returns the string employeeName. But why are we calling it "Clean code"? We are calling it "Clean Code" because of the following characteristics that it possesses:

  1. The variable, class, and method are named according to the naming convention. For example, the class has the first letter capital. The variable and method are named as per the camelCase naming convention, and they also reflect a specific meaning according to their names.
  2. We made sure that our method is doing only one thing i.e., getting employee names.
  3. Whitespaces and indentation are also properly utilized.

Why Should Your Code Have Low Coupling and High Cohesion?

Cohesion

In Java programming, Cohesion generally refers to the degree to which the elements of a module are functionally dependent on each other. It refers to the internal glue that keeps the module together.

It can also be said that all the related code should be bundled together in a single module. For example, if there are different classes, methods, variables, logic, etc. that are related to each other, they can be bundled together inside a single module. So, Cohesion, in particular, deals with the elements of the same module or class.

Coupling

Coupling generally refers to the degree to which the different classes/modules depend on each other. In simple words, all the modules should be as independent as possible. It also means that every module should be restricted to only one thing.

So, Coupling, in particular, deals with the elements of different modules or classes. If your code has low coupling and high cohesion, it will be easy to maintain, and debugging can become much more simple.

Takeaway:

Low coupling and high cohesion lead to easily maintainable code where debugging becomes very simple.

Tools to Write Clean Code

In this article, we have seen various practices and principles available for writing clean code. Certain tools can also help you write clean code if utilized effectively. For example, there are code formatters to format your code (using whitespaces and standard indentation) and some static analysis tools. Let us discuss them in detail.

  • Code Formatters: Automatic code formatting in popular Java code editors alleviates the need for manual formatting, ensuring consistent and clean code. Moreover, customization options allow programmers to tailor formatting to suit specific preferences.
  • Static Analysis Tools: For Java, there are many static code analysis tools available, such as Checkstyle, SonarQube, and SpotBugs, which offer a set of rules that can be applied to your projects.

Conclusion

  • The clean code should be simple, readable, maintainable, and testable.
  • The symptoms of bad code are that it is hard to read, unnecessary complex, and difficult to test and maintain.
  • Hard coding should be avoided when writing quality code. If the project grows in size, hardcoding can lead to serious maintainability issues.
  • DRY focuses on code reusability.
  • KISS focuses on making to code simple to understand.
  • A Good Code should has low coupling and high cohesion.