Clean Code and Design Principles Complete Guide
- Introduction to Clean Code and Software Design Principles
- Writing Meaningful Variable Names
- Designing Good Functions and Classes
- Software Design Principles - I (DRY, YAGNI, KISS, etc)
- Software Design Principles - II (Abstraction, Extensibility, Cohesion)
- Software Design Principles - III (SOLID Principles)
We can write clean code by following a set of guidelines known as Software Design Principles. Software Design Principles is a set of guidelines proven to work over the years.
I've listed down some of the most popular and useful design principles. You should try to enforce them in your code with every iteration.
This is the second part of the Software Design Principles Series.
Hide Implementation Details
Hiding implementation details helps to make changes in a component without making changes in the other modules/clients using that component. This can be achieved by creating interfaces and using them instead of the concrete classes.
Encapsulation with proper access management should also be done to expose only the required public functions.
Separation of Concerns
Separation of concerns (SoC) is a design principle for separating a computer program into distinct sections such that each section addresses a separate concern.
A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by creating well-encapsulated classes that have well-defined interfaces.
We should strive to separate the program into separate sections such that the overlap is as minimal as possible. SoC helps maintenance and also code reuse.
Maximize Cohesion
Cohesion is the degree to how strongly related and focused are the various responsibilities of a module. It is a measure of the strength of the relationship between the class’s methods and data themselves. We should strive to maximize cohesion. High cohesion results in better understanding, maintaining, and reusing components.
Cohesion is increased if:
- The functionalities embedded in a class, accessed through its methods, have much in common.
- Methods carry out a small number of related activities, by avoiding coarsely grained or unrelated sets of data.
- Related methods are in the same source file or otherwise grouped together; for example, in separate files but in the same sub-directory/folder.
Minimize Coupling
Coupling is the degree to which each module depends on other modules; a measure of how closely connected two modules are. We should strive to minimize coupling.
Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion and vice versa.
Tightly coupled modules have the following disadvantages:
- Change in one module might break another module.
- Change in one module usually forces a ripple effect of changes in other modules.
- Reusability decreases as dependency over other modules increases.
- Assembly of modules might require more effort and/or time.
Coupling can be reduced by:
- By hiding inner details and interacting through interfaces.
- Avoid interacting with classes that it can avoid directly dealing with.
Components in a loosely coupled system can be replaced with alternative implementations that provide the same services.
Law of Demeter/Principle of Least Knowledge
Code components should only talk to its direct relations and not to strangers.
The Law of Demeter for functions requires that a method m of an object a may only invoke the methods of the following kinds of objects:
aitself;m's parameters;- any objects instantiated within
m; a's attributes;- global variables accessible by
ain the scope ofm.
In particular, an object should avoid invoking methods of an object returned by another method. For many modern object-oriented languages that use a dot as a field identifier, the law can be stated simply as "use only one dot". That is, the code a.m().n() breaks the law where a.m() does not. As an analogy, when one wants a dog to walk, one does not command the dog's legs to walk directly; instead one commands the dog which then commands its own legs.
Command-Query Separation
Command-Query Separation (CQS) states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer.
Query: Returns a result without changing the state. Command: Changes the state but does not return any value.
This way the query method could be used anywhere without changing the data/state. We should apply naming conventions (get, set, add, etc.) to imply whether it is a command or a query.
References:
---
Read next






