Solid Principle - singhmahabir/allinone-rest-services GitHub Wiki

Why use SOLID principles

Let’s look at the possible issues below that may occur in the code if we don’t adhere to the SOLID principles.

  • The code may become tightly coupled with several components, which makes it difficult to integrate new features or bug fixes and sometimes leads to unidentified problems.
  • The code will be untestable, which effectively means that every change will need end-to-end testing.
  • The code may have a lot of duplication.
  • Fixing one issue results in additional errors.

However, if we adhere to the SOLID principles, we are able to do the following:

  • Reduce the tight coupling of the code, which reduces errors.
  • Reduce the code’s complexity for future use.
  • Produce more extensible, maintainable, and understandable software code.
  • Produce the code that is modular, feature specific, and is extremely testable.

Design principles

Let’s look at the definition of the five design principles.

  • In the Single Responsibility Principle (SRP), each class should be responsible for a single part or functionality of the system.
  • In the Open Closed principle (OCP), software components should be open for extension but closed for modification.
  • In the Liskov Substitution Principle (LSP), objects of a superclass should be replaceable with objects of its subclasses without breaking the system.
  • The Interface Segregation Principle (ISP) makes fine-grained interfaces that are client specific.
  • The Dependency Inversion Principle (DIP), ensures that the high-level modules are not dependent on low-level modules. In other words, one should depend upon abstraction and not concretion.

SOLID: Single Responsibility Principle

Introduction

The Single Responsibility Principle (SRP) is perhaps the least understood of the SOLID concepts. The term was coined by Robert C. Martin, who defines the SRP in the following way, “A class should have only one reason to change.” This implies that any class or component in our code should only have one functionality. Everything in the class should be related to just one goal.

When programmers need to add features or new behavior, they frequently integrate everything within the current class. When something needs to be changed later, due to the complexity of the code, the update process becomes extremely time-consuming and tedious. The Single Responsibility Principle helps us create simple classes that perform just one task. This helps in making modifications or adding extensions to the existing code much easier.

Book invoice application

Let’s try to understand SRP with the help of an example. We have a book invoice application that has two classes: Book and Invoice. The Book class contains the data members related to the book. Whereas, the Invoice class contains the following three functionalities:

  • Calculating the price of the book
  • Printing the invoice
  • Saving the invoice into the database

The following class diagram provides a blueprint of these classes:

Violations

If we notice, the Invoice class violates the SRP in multiple ways:

The Invoice class is about invoices, but we have added print and storage functionality inside it. This breaks the SRP rule, which states, “A class should have only one reason to change.”

If we want to change the logic of the printing or storage functionality in the future, we would need to change the class.

Instead of modifying the Invoice class for these uses, we can create two new classes for printing and persistence logic: InvoicePrinter and InvoiceStorage, and move the methods accordingly, as shown below.