Enhancing Code Readability: 5 Simple Guidelines for Clean Code
Written on
Chapter 1: The Importance of Clean Code
Crafting clean code is a vital competency for any proficient software engineer. Our coding efforts should not only cater to machines but, more importantly, to other developers who will later interpret our work. Upon merging our code into a repository, it is likely that numerous individuals will read it and attempt to understand our intentions—perhaps during a code review. As Robert C. Martin famously stated, "Clean code reads like well-written prose." The following guidelines aim to facilitate this principle.
While I will illustrate these points using Java code, the concepts are applicable across various programming languages.
Section 1.1: Avoid Magic Numbers and Strings
Magic numbers and strings are those values in your code that lack clear explanation, rendering their purpose ambiguous. For instance, consider a scenario where we calculate annual bonuses for employees. The bonus is determined by multiplying the monthly salary by a performance multiplier, currently set at 1.11.
Example Code:
public class Employee {
private int id;
private String firstName;
private String lastName;
private double monthlySalary;
// constructor, getters, and setters...
}
The calculation logic would be:
public class AnnualBonusCalculator {
public static double calculate(Employee employee) {
return employee.getMonthlySalary() * 1.11;}
}
Here, the use of the number 1.11 is unclear. To enhance clarity, we can define it as a constant:
public class AnnualBonusCalculator {
private final static double PERFORMANCE_MULTIPLIER = 1.11;
public static double calculate(Employee employee) {
return employee.getMonthlySalary() * PERFORMANCE_MULTIPLIER;}
}
This modification clarifies the code's intention.
Section 1.2: Adhere to the DRY Principle
Duplicating code can lead to numerous issues, the most significant being that a change in one location may not be replicated elsewhere. This can create inconsistencies and bugs. The DRY (Don't Repeat Yourself) principle was established to combat this problem.
For example, when creating a Rectangle class with validation for side lengths:
public class Rectangle {
private double a;
private double b;
public Rectangle(double a, double b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException();}
this.a = a;
this.b = b;
}
// Getters and setters...
}
By extracting the validation logic, we can streamline our code:
public class Rectangle {
private double a;
private double b;
public Rectangle(double a, double b) {
validateSide(a);
validateSide(b);
this.a = a;
this.b = b;
}
private void validateSide(double side) {
if (side < 0) {
throw new IllegalArgumentException();}
}
}
This adjustment minimizes redundancy.
Section 1.3: Maintain Consistency in Code
As emphasized by an early mentor, "Your code can be flawed, but it must be consistent." Employing linters and adhering to established code styles can assist in achieving this consistency.
Example of inconsistent code:
public class Person {
private int id;
private String firstName;
private String last_name;
private int Age;
// Constructor and methods...
}
A more consistent version would look like this:
public class Person {
private int id;
private String firstName;
private String lastName;
private int age;
// Constructor and methods...
}
Section 1.4: Keep Methods and Classes Concise
In the words of Uncle Bob: "Functions should be small. The second rule of functions is that they should be smaller than that." Smaller functions enhance maintainability and readability.
Example of a lengthy method:
public double getDistanceToAttraction(int attractionId, float userLat, float userLon) {
// Logic...
}
Refactoring this to smaller methods improves clarity:
public double getDistanceToAttraction(int attractionId, float userLat, float userLon) {
Attraction attraction = findAttraction(attractionId);
return calculateDistance(attraction, userLat, userLon);
}
// Additional methods...
Section 1.5: The Importance of Testing
Testing is crucial, not just for verifying functionality but also for ensuring future changes do not introduce new issues. Tools like IntelliJ offer excellent coverage reports to help you ascertain which parts of your code are tested.
Summary
By implementing these guidelines, your code quality will significantly improve. While these rules are just a subset of the principles surrounding clean code, they are among the most critical. If you have any questions or need clarification, please feel free to comment. If you found this article beneficial, I would appreciate a clap and a follow for more insights.