Bhavanam Venkata Suresh Reddy
Clean Coding Techniques
208
Bhavanam Venkata Suresh Reddy
Clean Coding Techniques
Honestly, there can not be one good answer to this.
But then, every programming language and paradigm present their own
set of nuances, which mandates us to adopt befitting practices.
clean code can be summarized as a code that any developer can
read and change easily.
209
Bhavanam Venkata Suresh Reddy
Martin Fowler
Any fool can write code that a computer can
understand. Good programmers write code that
humans can understand.
210
Bhavanam Venkata Suresh Reddy
Why Should We Care About Clean Code?
Maintainable Codebase
Easier Troubleshooting
Faster Onboarding
211
Bhavanam Venkata Suresh Reddy
Maintainable Writing clean code is crucial because it makes it easier to
Why Should We Care About Clean
Codebase
update and maintain software over time, ensuring its usefulness
and longevity.
Easier Fixing problems in software becomes easier and faster when
Troubleshooting
Code
the software is built using clean coding principles, whether the
issues are caused by internal or external factors.
Faster To keep a software project running smoothly as different
Onboarding
developers come and go, it's important to have clean code for
faster onboarding and higher productivity.
212
Bhavanam Venkata Suresh Reddy
This leads to a lower total cost of ownership for the software lifecycle.
Focused code should be written to solve a specific problem
Characteristics of Clean
Simple software design and implementation must be as simple
as possible
Code
Testable It must be intuitive and easy to test the codebase,
preferably in an automated manner.
213
Bhavanam Venkata Suresh Reddy
Clean Coding In Java
Java offers a lot of best practices that can help us write clean
code.
We’ll categorize them in different buckets and understand how
to write clean code with code samples.
214
Bhavanam Venkata Suresh Reddy
Project Structure
Clean Coding Techniques Naming Convention
Source File Structure
Whitespaces
Indentation
Method Parameters
Hardcoding
Code Comments
Logging
SOLID Principles
DRY & KISS
TDD
215
Bhavanam Venkata Suresh Reddy
Project Structure
While Java doesn’t enforce any project structure, it’s always useful to
follow a consistent pattern to organize our source files, tests,
configurations, data, and other code artifacts.
Maven, a popular build tool for Java, prescribes a particular project structure.
While we may not use Maven, it’s always nice to stick to a convention.
216
Bhavanam Venkata Suresh Reddy
Some Of The Folders That Maven Suggests
src/main/java : For source files
src/main/resources : For resource files, like properties
src/test/java : For test source files
src/test/resources : For test resource files, like properties
217
Bhavanam Venkata Suresh Reddy
Building Java Applications With Bazel
Similar to this, there are other popular project structures like
Bazel suggested for Java, and we should choose one depending on our needs
and audience.
218
Bhavanam Venkata Suresh Reddy
Naming Convention
Naming conventions can go a long way in making our code readable and
hence, maintainable.
Java prescribes a set of rules to adhere to when it comes to naming
anything in Java. A well-formed name does not only help in reading the
code, but it also conveys a lot about the intention of the code.
219
Bhavanam Venkata Suresh Reddy
Naming Convention
Classes
Variables
Methods
220
Bhavanam Venkata Suresh Reddy
Naming Convention
Classes : Class in terms of object-oriented concepts is a blueprint for
objects which often represent real-world objects. Hence it’s meaningful to
use nouns to name classes describing them sufficiently:
Syntax : public class Customer { }
221
Bhavanam Venkata Suresh Reddy
Naming Convention
Classes : Class in terms of Syntax : public class Customer {
object-oriented concepts is a
blueprint for objects which
}
often represent real-world
objects. Hence it’s meaningful
to use nouns to name classes
describing them sufficiently:
222
Bhavanam Venkata Suresh Reddy
Naming Convention
Variables:Variables in Java Syntax : public class Customer {
capture the state of the private String customerName;
object created from a class.
}
The name of the variable
should describe the intent
of the variable clearly:
223
Bhavanam Venkata Suresh Reddy
Naming Convention
Methods: Methods in Java Syntax : public class Customer {
are always part of classes and private String customerName;
hence generally represent an
public String getCustomerName( ) {
action on the state of the
object created from the class. return this.customerName;
It’s hence useful to name }
methods using verbs: }
224
Bhavanam Venkata Suresh Reddy
Source File Structure
A source file can contain different elements. While Java compiler
enforces some structure, a large part is fluid. But adhering to a
specific order in which to place elements in a source file can significantly
improve code readability. There are multiple popular style-guides to take
inspiration from, like one by Google and another by Spring.
225
Bhavanam Venkata Suresh Reddy
A Typical Ordering Of Elements In A Source File
Package statement
Import statements
• All static imports
• All non-static imports
Exactly one top-level class
• Class variables
• Instance variables
• Constructors
• Methods
226
Bhavanam Venkata Suresh Reddy
Source File Structure
Apart from the above, methods can be grouped based on their
functionality or scope. There is no one good convention, and the idea
should be decided once and then followed consistently.
227
Bhavanam Venkata Suresh Reddy
Source File Structure
# /src/main/java/com/sures/application/entity/Customer.java
package com.aoop.application.entity;
import java.util.Date;
public class Customer {
private String customerName;
private Date joiningDate;
228
Bhavanam Venkata Suresh Reddy
Source File Structure
public Customer(String customerName) {
this.customerName = customerName;
this.joiningDate = new Date();
}
public String getCustomerName() {
return this.customerName;
}
229
Bhavanam Venkata Suresh Reddy
Source File Structure
public Date getJoiningDate() {
return this.joiningDate;
}
}
230
Bhavanam Venkata Suresh Reddy
Whitespaces
We all know that it is easier to read and understand short paragraphs
compared to a large block of text. It is not very different when it comes to
reading code as well. Well-placed and consistent whitespaces and blank lines
can enhance the readability of the code.
The idea here is to introduce logical groupings in the code which can help
organize thought processes while trying to read it through. There is no one
single rule to adopt here but a general set of guidelines and an inherent
intention to keep readability at the center of it:
231
Bhavanam Venkata Suresh Reddy
Whitespaces
Two blank lines before starting static blocks, fields, constructors and inner
classes
One blank line after a method signature that is multiline
A single space separating reserved keywords like if, for, catch from an
open parentheses
A single space separating reserved keywords like else, catch from a closing
parentheses.
232
Bhavanam Venkata Suresh Reddy
Indentation
A well-indented code is much easier to read and understand.
A typical best practice is to use four spaces, a unit of indentation. Please
note that some guidelines suggest a tab instead of spaces.
Normally, there should be a cap over the line length, but this can be set
higher than traditional 80 owing to larger screens developers use today.
233
Bhavanam Venkata Suresh Reddy
Indentation
Lastly, since many expressions will not fit into a single line, we must break
them consistently:
• Break method calls after a comma
• Break expressions before an operator
• Indent wrapped lines for better readability
234
Bhavanam Venkata Suresh Reddy
Indentation
Syntax :
List<String> customerIds = customer.stream()
.map(customer -> customer.getCustomerId())
.collect(Collectors.toCollection(ArrayList::new));
235
Bhavanam Venkata Suresh Reddy
Method Parameters
Parameters are essential for methods to work as per specification.
But, a long list of parameters can make it difficult for someone to
read and understand the code.
236
Bhavanam Venkata Suresh Reddy
Method Parameters
Restrict the number of parameters a method accepts, three parameters
can be one good choice
Consider refactoring the method if it needs more than recommended
parameters, typically a long parameter list also indicate that the method
may be doing multiple things.
We may consider bundling parameters into custom-types but must be
careful not to dump unrelated parameters into a single type.
237
Bhavanam Venkata Suresh Reddy
Method Parameters
public boolean setCustomerAddress(String firstName, String lastName,
String streetAddress, String city, String zipCode, String state, String
country, String phoneNumber) {
}
// This can be refactored as below to increase readability
public boolean setCustomerAddress(Address address) {
238
Bhavanam Venkata Suresh Reddy
Hardcoding
Hardcoding values in code can lead to duplication, which makes
change more difficult. It can often lead to undesirable behavior if the
values need to be dynamic.
239
Bhavanam Venkata Suresh Reddy
Hardcoding
In most of the cases, hardcoded values can be refactored in one of the
following ways:
• Consider replacing with constants or enums defined within Java
• Or else, replace with constants defined at the class level or in a
separate class file
• If possible, replace with values which can be picked from configuration
or environment
240
Bhavanam Venkata Suresh Reddy
Hardcoding
Syntax :
private int storeClosureDay = 7;
// This can be refactored to use a constant from Java
private int storeClosureDay = DayOfWeek.SUNDAY.getValue()
241
Bhavanam Venkata Suresh Reddy
Code Comments
Code comments can be beneficial while reading code to
understand the non-trivial aspects. At the same time, care should be
taken to not include obvious things in the comments. This can bloat
comments making it difficult to read the relevant parts.
242
Bhavanam Venkata Suresh Reddy
Code Comments
Java allows two types of comments:
• Implementation comments
• documentation comments.
243
Bhavanam Venkata Suresh Reddy
Code Comments
Documentation/JavaDoc Comments
• The audience here is the users of the codebase
• The details here are typically implementation free, focusing more on
the specification
• Typically useful independent of the codebase
244
Bhavanam Venkata Suresh Reddy
Code Comments
Implementation/Block Comments
• The audience here is the developers working on the codebase
• The details here are implementation-specific
• Typically useful together with the codebase
245
Bhavanam Venkata Suresh Reddy
Code Comments
So, how should we optimally use them so that they are useful and
contextual?
• Comments should only complement a code, if we are not able to
understand the code without comments, perhaps we need to refactor
it
• We should use block comments rarely, possibly to describe non-trivial
design decisions.
246
Bhavanam Venkata Suresh Reddy
Code Comments
So, how should we optimally use them so that they are useful and
contextual?
• We should use JavaDoc comments for most of our classes, interfaces,
public and protected methods
• All comments should be well-formed with a proper indentation for
readability
247
Bhavanam Venkata Suresh Reddy
Code Comments
Syntax :
/**
* This method is intended to add a new address for the customer. However
*do note that it only allows a single address per zip code. Hence, this will
*override any previous address with the same postal code.
* @param address an address to be added for an existing customer
*/
248
Bhavanam Venkata Suresh Reddy
Code Comments
Syntax :
/*
* This method makes use of the custom implementation of equals
* method to avoid duplication of an address with same zip code.
*/
public addCustomerAddress(Address address) {
}
249
Bhavanam Venkata Suresh Reddy
Logging
logger.info(String.format("A new customer has been created with customer
Id: %s", id));
250
Bhavanam Venkata Suresh Reddy
SOLID
SOLID is a mnemonic acronym that draws from the five principles it sets
forth for writing understandable and maintainable software:
• Single Responsibility Principle
• Open-Closed Principle
• Liskov Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
251
Bhavanam Venkata Suresh Reddy
Single Responsibility Each interface, class, or method we create should have a clear purpose,
Principle ideally performing one task well, resulting in smaller, more testable
code.
Open-Closed Code should be designed so that we can add new functionality without
Principle changing the existing code, promoting extension through inheritance or
composition.
Liskov Substitution Every derived class should be able to replace its parent class without
Principle affecting the program's correctness, promoting code flexibility and
reusability.
Interface Implementing an interface allows a class to have specific behavior, but
Segregation Principle it's important to create smaller interfaces so that classes don't have to
implement unnecessary methods.
Dependency Classes should rely on general concepts, not specific details, and should
Inversion Principle not create their own dependencies but instead have them provided
from outside.
252
Bhavanam Venkata Suresh Reddy
DRY & KISS
DRY stands for “Don’s Repeat Yourself”. This principle states that a piece
of code should not be repeated across the software.
The rationale behind this principle is to reduce duplication and increase
reusability.
we should be careful in adopting this rather too literally. Some duplication
can actually improve code readability and maintainability.
253
Bhavanam Venkata Suresh Reddy
DRY & KISS
KISS stands for “Keep It Simple, Stupid”. This principle states that we
should try to keep the code as simple as possible.
This makes it easy to understand and maintain over time.
254
Bhavanam Venkata Suresh Reddy
255