SOLID Principles with Examples – Guidelines
SOLID principles are core principles of software development that can be followed while designing software.
These principles are the result of a decade of experiences around the real-world common software development problems and solutions around them. These principles make your software products robust, extensible, and maintainable.
Today in this article, we will cover below aspects,
“SOLID principles are abstract and language-agnostic in nature”.
The SOLID principles of Object-Oriented Design include five principles,
- Single Responsibility Principle(SRP)
- Open/Closed Principle(OCP)
- Liskov Substitution Principle(LSP )
- Interface Segregation Principle(ISP )
- Dependency Inversion Principle(DIP)
Let’s get started with the Single Responsibility Principle(SRP) with a few examples using C# code.
Single Responsibility Principle(SRP)
The single responsibility principle talks about the Class and its behavioral characteristics.
“Class should be created using single responsibility principle “
Each Class should have only one reason to change.
As we understand classes are just templates until defined with proper behavior.
The behavior of a class is defined by its properties, fields, and functions.
If these behavioral characteristics are making a Class change more than once then there is scope to rethink the class design and there could be a chance to break the class into the subclasss if needed.
However, you should not do it to all classes where there is no pain.
A few examples of motivating class change are validation, parser, and data extraction.
Let’s take a simple example of the Employee class,
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public DateTime JoiningDate { get; set; }
public string PhoneNumber { get; set; }
public string SSN { get; set; }
public string Location { get; set; }
}
Let’s say as per new requirements you would like to extract the last 4 digits of SSN and validate it for correctness.
Then you shall end up adding extraction logic as below,
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int ID { get; set; }
public DateTime JoiningDate { get; set; }
public string PhoneNumber { get; set; }
public string SSN { get; set; }
public string Location { get; set; }
public string GetLast4Digit()
{
var index = SSN.LastIndexOf("-", StringComparison.Ordinal);
return index > 0 && index < SSN.Length
? SSN.Substring(index + 1, SSN.Length - index + 1)
: SSN;
}
}
The problem with the above implementation,
GetLast4Digit methods would produce the desired results but there are a few problems as listed below,
- The extraction or formatting logic of SSN is owned by the Employee class
- Employee class is now more reason to change due to additional behavior.
- You will end up instantiating the Employee class so that you can use the GetLast4Digit() method at other locations which is unnecessary.
- Also, if similar SSN extraction or validation logic is needed in other parts of your application, then the code will be duplicated. (Code Smell)
Let’s combine the behavior and look for the opportunity for Class updates as below,
Let’s look to make each reason for change as speculated above into single responsibility classes,
The class diagram as below,
Above as we understood Employee class was broken up into a few highly cohesive classes.
Each class now could be easily used by other components of the system. Each class now has its responsibility.
By bringing responsibility together, Objects become a logical container by packaging data with its behavior as new methods/functions.
Any change in any one of them would have a lesser impact on the total system.
Using this principle you bring in your domain properties and their validation logic together so that the domain model which gets built over this can be used across your application supporting the DRY (Do Not Repeat) principle.
I shall be talking in the next article about the Open/Closed Principle(OCP), Liskov Substitution Principle(LSP ), Interface Segregation Principle(ISP ) Dependency Inversion Principle(DIP).
Do you have any comments or ideas or any better suggestions to share?
Please sound off your comments below.
Happy Coding !!
Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.