0% found this document useful (0 votes)
5 views17 pages

Clean Coding Notes_updated (1)

Clean coding emphasizes writing code that is readable, maintainable, and less prone to errors, with characteristics such as simplicity and testability. It includes practices like proper naming, avoiding hardcoding, and following SOLID principles to enhance code quality. Additionally, it addresses code smells, which are signs of potential weaknesses in design that may lead to future bugs and maintenance challenges.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views17 pages

Clean Coding Notes_updated (1)

Clean coding emphasizes writing code that is readable, maintainable, and less prone to errors, with characteristics such as simplicity and testability. It includes practices like proper naming, avoiding hardcoding, and following SOLID principles to enhance code quality. Additionally, it addresses code smells, which are signs of potential weaknesses in design that may lead to future bugs and maintenance challenges.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

CLEAN CODING

Clean code makes the code more readable and hence easily maintainable. In
short, clean coding is the way of writing the code such that it is easily readable,
testable and less prone to errors.

What is a clean code? The code that is easily readable, modifiable,


scalable(in some cases), maintainable and is less prone to errors is referred
as "Clean Code". Less prone to errors means that there will be very less
chances of getting bugs in that code.

Characteristics of Clean Code:

1. Simple: the code should be made as simple as possible.


2. Maintainable: It should be maintainable in the long run as many
different developers can work on that code.
3. Testable: It should be easily testable and less prone to errors.
4. Readable: it should be easily readable.

Symptoms of bad code (Unclean code)

any code that leads to problems in the long run can be referred to as Bad Code.
The problems can be:

1. Hard to read code


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

To write Clean Code in Java:

1. Structure

there is no such rule to follow a particular structure for your project but it does
not mean that you should not.
src
├── main
│ ├── java
│ └── resources
└── test
├── java
└── resources

 1. src/main/java: It contains the source files of your project. You can


identify it as the sub-folder is main in this case.
 2. src/main/resources: It contains the resource files of your project. You
can identify it as the sub-folder is main in this case also.
 3. src/test/java: It contains the test source files of your project. You can
identify it as the sub-folder is test in this case.
 4. src/test/resources: It contains the test resource files of your project.
You can identify it as the sub-folder is test in this case also.

2. Proper Naming

In Java, we have to name variables, classes, methods, etc., hence we should


always give them a name that they can relate to.

For example, If you want to create a variable for counting, name it 'counter'
instead of naming it 'c' or something like that. You should always avoid
naming variables with a single character like 'a', 'b', 'c', etc.

3. Source File Structure

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

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

4. Whitespaces and Indentation


Whitespaces can help you make your code very readable that is why it is
advised to add whitespaces whenever you can add them.
In this function, whitespaces and indentation are not taken care of.

public int sum(int num1,int num2,int num3)


{
int sum=num1+num2+num3;
return sum;
}

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

public int sum (int num1, int num2, int num3)


{
int sum = num1 + num2 + num3;
return sum;
}

5. Method Parameters
avoid adding more than 3 parameters if possible as it can create unnecessary
confusion for other developers or programmers who are going to deal with that
code in future.

You can also go for refactoring if possible, like we have done in the example
given below:

In Programming, Refactoring is a technique used for restructuring an existing


code without modifying the external behaviour of code.

// before
private void employeeDetails(String name, String age, String awards,
String ctc, String experience).
// after
private void employeeDetails(String name, Details employeeDetails).

6. Avoid Hardcoding
Hardcoding is the practice of adding the data directly into the source code of a
program instead of getting the data from external sources. Remember that heavy
hardcoding can make your program difficult to maintain and it also leads to
bugs in your program.
some common practices to avoid hard-coding in Java:
1. Use Constants
Define constants for values that do not change. This way, you can change the
value in one place if needed.

2. Use Configuration Files


Store configuration values in external files such as properties files, XML files,
or JSON files, and load them at runtime.
Example: using a properties file (config.properties):
database.url = jdbc:mysql://localhost:3306/mydatabase
timeout=30

7. Code Comments
Commenting is also considered as one of the best practises to make the code
easily understandable.
In Java, two kinds of comments are allowed:
 Documentation comments [ /**…. */ ] - Documentation comments are
usually used to write large programs for a project or software application
as it helps to create documentation API. These APIs are needed for
reference, i.e., which classes, methods, arguments, etc., are used in the
code.
 Single line comments [ // ]- The single-line comment is used to comment
only one line of the code. It is the widely used and easiest way of
commenting the statements.
 The multi-line comment [ /* …. */ ] is used to comment multiple lines
of code.
8. Logging
Logging in Java is the process of recording information about a program's
execution for debugging, monitoring, and auditing purposes. Logs can help
developers understand what the application is doing, track down bugs, and
monitor application performance.
Logging is one of the most important factors in clean coding. A well logged
code is easy to debug and can save hours of work for a developer.
Key Concepts of Logging
1. Logger: The main component used to log messages. It is responsible for
sending log messages to different destinations (known as handlers or
appenders).
2. Log Levels: Indicates the severity or importance of a log message.
Common log levels include:
o FATAL: Severe error that will prevent the application from
continuing.
o ERROR: An error that might allow the application to continue
running.
o WARN: Potentially harmful situation.
o INFO: General informational messages that highlight the progress
of the application.
o DEBUG: Detailed information on the flow through the system,
mainly used for debugging.
o TRACE: Even more detailed information than debug.

9. S.O.L.I.D principles:
The SOLID principles are five design principles intended to make software
designs more understandable, flexible, and maintainable.

SOLID is a mnemonic acronym for the five principles given below:




 Single Responsibility Principle (SRP)
 Open/Closed Principle (OCP)
 Liskov Substitution Principle (LSP)
 Interface Segregation Principle (ISP)
 Dependency Inversion Principle (DIP)

 Single Responsibility Principle: This principle states that, In Java, each


and every interface, class, or method that is defined by us should be very
specific which means that it should have a single responsibility. In simple
words, it should do only one task and do it really well. By following this
principle consistently, the code become smaller hence easily testable.

 Principle: A class should have only one reason to change, meaning it


should have only one job or responsibility.

Example:

Imagine you have a Book class. The Book class should only handle
things related to the book itself, like getting the title or author. If you also
add code to print the book, it would violate SRP.
 Open-Closed Principle: This principle states that our code should
ideally be open to any kind of extension and closed for any type of
modification. In simple words, our code should be easy to extend but
good enough that no modification is required in our code.

 Classes should be open for extension but closed for modification. This
means you should be able to add new functionality without changing
existing code.

 Example: Let's say we have a Shape class with a method to calculate area.
 Liskov Substitution Principle(LSP): This principle states that the
objects of a superclass should be replaceable with the objects of its
subclasses but without causing the application to break.

 Principle: Subtypes must be substitutable for their base types without


altering the correctness of the program.
 Example: If you have a Bird class, a subclass Ostrich should be able
to replace Bird without breaking the program.

 Interface Segregation Principle: Defined by Robert C., the goal of this


principle is 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.
 Principle: No client should be forced to depend on methods it does not
use. It’s better to have multiple small interfaces rather than one large one.
 Example: If you have an Animal interface with many methods, it might
be better to split it.

 Dependency Inversion Principle: According to this principle, classes


should only depend on the abstractions and not on the implementations.
In simple words, High-level(complex) modules, which provide complex
logic to your software should be easily reusable and they should not get
affected by the changes in the low-level modules which generally provide
utility features.

 Principle: High-level modules should not depend on low-level modules.


Both should depend on abstractions (interfaces). Abstractions should not
depend on details. Details should depend on abstractions.
 Example: Instead of a LightBulb class depending directly on a
Switch class, use an interface for the Switch.

10. DRY & KISS

DRY is an acronym that stands for "Don't Repeat Yourself". DRY emphasises
on not repeating the same code again and again. In simple words, the main
motive behind this principle is to make the code reusable.

KISS is an acronym that stands for "Keep It Simple, Stupid". As the words of
this acronym suggests, this principle states that the code should be made as
simple as possible which is of course to avoid the understanding confusions. If
this principle is followed properly, the whole code eventually becomes easy to
understand i.e. simple.

Example for Clean Code:


Why the above is called as Clean Code?

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

Code Smells
Code Smells are not the bugs of the program. With code smells too, your
program might work just fine. They do not prevent the program from
functioning or are incorrect. They just signify the weakness in design and
might increase the risk of bugs and program failure in the future.
Code Smells motivates for Code Refactoring(do changes in code and do not
change it behavior)

Types of Code Smells

 Within Classes
 Between Classes
Code Smells Within Classes

1. Comments: Yes, Comments are code smells too. It is like deodorant to


the code. If comments explain a few lines of complex code or a complex
expression, it should be made as a complete another function/ sub-
expression respectively.
2. Long Method: A long method contains too many lines of code. Any
code with more than 25 lines of code should make you question. It could
be solved using refactoring techniques like changing expression into
sub-expression, complex codes into a new function in order to make a
function or method a small and easy to read without changing its
functionality.

3. Long Parameter List: Any function with more parameters is obviously


more complex. One of the thumb rules is to use a maximum of 3 to 4
parameters in a function.
4. Large Classes: A class contains many methods/lines of code/fields is
considered a code smell. Refactoring techniques could be done like,
extract class, extract subclass, extract interface, duplicate observed data.
5. Duplicate Code: When a code is repeated for more than two times,
merge it into a function or a method of the class. If the same code is
found in two or more classes, using the extract method we can refactor
the code smell.
6. Dead Code: The code that is not being used. A function with no calls or
the condition that never occurs. Delete unused code and unnecessary
files.

Code Smells Between Classes

1. Data Classes: A class that just store data and no methods. These
classes don’t contain any functionality. They can’t independently
operate on the data that they own. A class should contain both
data and methods. Use global or local variables to refactor this code
smell. If the data class contains public data, we can use the
Encapsulation Method to hide it.

Other refactoring techniques to solve this are: Move, Extract, and


Remove Methods.
2. Data Clumps: Data that looks similar maybe belongs to the same
class. Consider using a superior class. For example, parameters for
connecting to a database. These clumps should be merged into a new
class. If data that is repeating data comprises the fields of a class, use
extract class to move the fields to their own class or create their own
class.

Other Refactoring Techniques to deal with this code smells are:


Introducing parameter objects, Preserve the whole objects, etc.

3. Alternative Classes with Different Interfaces: If two classes are


similar on the inside, perhaps they can be modified to share a
common interface. For example, The programmer who created one of
the classes is might not aware that a similar class already existed or
created by other programmers of the team.
Refactoring Techniques to deal with them are: Rename Method,
Move, Add Parameter, Parameterize Method.

4. Refused Bequest: A class inherits from other classes but not using
the inheritance methods of its parent class. For example, Assume a
class, body, human class, and animal class both are inherited from
the class body. A car has a body too, it could inherit from the body
class too, but that will not make any sense.
Refactoring Techniques to deal with this are: Replace inheritance
with the delegation and Extract superclass.

5. Lazy Class: A class doesn’t do enough to earn your attention, it


should be deleted because it can cost your time and money both. For
Example, a class that was designed to be fully functional but after
some refactoring and change in code, it has become of no use or a
little use maybe.
Inline Class and Collapsing Hierarchy can be used to make the code
size smaller, easy to understand and maintain.

6. Shotgun Surgery: A single fire causing multiple shots. A single


change in classes may lead to cascading changes in several related
classes. This can happen after the overzealous application of
Divergent Change. Use of Move Method and Move Field could be
done to make the code easier to maintain and less duplicated.
There are many known code smells that have been categorized as follows:

1. Bloaters:
 Bloaters are code, methods, or classes that have grown excessively large.
They can make the code harder to understand and maintain.
 Long Method: Methods that are too long and do too much.
 Large Class: Classes that have too many responsibilities or too many
methods and fields.
 Primitive Obsession: Overuse of primitive data types instead of small
objects for simple tasks.
 Long Parameter List: Methods that take too many parameters.
 Data Clumps: Groups of data that frequently appear together.

2. Object-Orientation Abusers: All these smells are incomplete or


incorrect application of object-oriented programming principles. Switch
Statements, Temporary Field, Refused Request and Alternative Classes
with Different Interface are known as object-orientation abusers code
smells.
3. Change Preventers: These smells mean that if you need to change
something in one place in your code, you have to make many changes in
other places too. Program development becomes much more complicated
and expensive as a result. Code smells like Divergent Change, Shotgun
Surgery and Parallel Inheritance Hierarchies are in this category.
4. Dispensables: A dispensable is something pointless and unneeded whose
absence would make the code cleaner, more efficient and easier to
understand like Comments, Duplicate Code, Lazy Class, Data Class,
Dead Code and Speculative Generality.
5. Couplers: All the smells in this group contribute to excessive coupling
between classes or show what happens if coupling is replaced by
excessive delegation. Some examples would be Feature Envy,
Inappropriate Intimacy, Message Chains, Middle Man and Incomplete
Library Class

Refer this link for more detailed explanation about each category of Code
smells: https://sourcemaking.com/refactoring/smells

You might also like