In Focus

Learn About SOLID Principles

SOLID Principles are the design principles that enable us manage most software design problems. In this article, we will discuss these principles in detail.

 In this lesson, we will learn the following.

  1. SOLID Acronym and Introduction
  2. SOLID Design Principles
  3. Why do we need to adapt SOLID

Let’s now discuss SOLID principles in details

Acronym

SOLID Acronym Short Description
S SRP Single Responsibility Principles
O OCP Open Closed Principles
L LSP LISKOV substitution principles
I ISP Interface Segregation Principles
D DIP Dependency Inverse Principles
 

Introduction

  • SOLID Principles are the design principles that enable us to manage most of the software design problems. These principles are intended to make software design more understandable, flexible, and maintainable.
  • These five principles are a subset of many other principles promoted by Robert C. Martin (Uncle Bob). Their acronyms were first introduced by Michael Feathers.

The motivation of using SOLID

  • Maintainability
  • Testability
  • Flexibility and Extensibility
  • Parallel Development
  • Loose Coupling

Single Responsibility Principles

Uncle Bob expresses the principle as “A class should have only one reason to change”. Everything in a class should be related to a single purpose. There can be many members in a class as long as they are related to a single responsibility. With the help of SRP, classes become smaller and cleaner.

Some examples of responsibilities to consider that may need to be separated include -

  • Persistence
  • Validation
  • Notification
  • Error Handling
  • Logging
  • Class Selection / Instantiation
  • Formatting
  • Parsing
  • Mapping

Interface Segregation Principle

This principle was first used and formulated by Robert C. Martin (Uncle Bob) while consulting for Xerox.

  • No client should be forced to depend on methods they do not use.
  • One heavy interface needs to be split into many smaller and relevant interfaces so that the clients can know about the interfaces that are relevant to them.

We will take a case study which Uncle Box resolved for Xerox.

Problem

  • Xerox had created a new printer system that could perform a variety of tasks such as stapling and faxing along with regular printing tasks.
  • The software for this system was created from the ground up.
  • Modifications and Deployment to the system became more complex

The design problem was that a single job class was used by almost all of the tasks.

Solution

  • One large job class is segregated to multiple interfaces depending on the requirements

Actually, if you add methods that shouldn’t be there, the classes implementing the interface will have to implement those methods as well. That is why; the client shouldn’t be forced to depend on interfaces that they don’t use. ISP is intended to keep a system decoupled and thus easier to refactor, change, and deploy. Refer to the .NET code snippet attached with this tutorial.

If you look at the previous section, you could see that the interface has been segregated based on the requirements.

Open Closed Principles

This section covers

  1. Open closed principle
  2. Implementation guidelines
  3. Example

Open Closed principle

  • Software entities such as classes, modules, functions, etc. should be open for extension but closed for modification.
  • Any new functionality should be implemented by adding new classes, attributes and methods, instead of changing the current ones or existing ones.
  • Bertrand Meyer originated the term OCP
  • Robert C. Martin (Uncle Bob) considered this as the most important principle of object oriented design

Implementation Guidelines

  • The simplest way to apply OCP is to implement the new functionality on new derived classes.
  • Allow the client to access the original class with the abstract interface.

Why OCP?

If not followed:

  • End up testing the entire functionality
  • QA team need to test the entire flow
  • Costly process for the organization
  • Breaks the single responsibility as well.
  • Maintenance overheads increase in the classes.

Example

Refer to the .NET code snippet attached, an Employee class calculating bonus based on the employee types (Permanent and Contract)

Liskov Substitution Principle

This section covers

  1. Liskov Substitution principle
  2. Implementation guidelines
  3. Example

Liskov Substitution principle

  • “S is a subtype of T, and then objects of type T may be replaced with an object of type S”
  • Derived types must be completely substitutable for their base types.
  • LSP is a particular definition of a sub-typing relation, called (strong) behavioral sub-typing.
  • Introduced by Barbara Liskov
  • Extension of Open closed principle

Implementation Guidelines

  • No new exception can be thrown by the sub-type.
  • Client should not know which specific sub-type they are calling
  • New derived classes just extend without replacing the functionality of old classes.

It may be confusion, but this can be achieved through a simple example. Please refer the attached .NET sample (LSP folder)

Dependency Inversion Principle

Here, let us cover:

  • Dependency Inversion Principle
  • Understanding the intention of DIP usage.

Dependency Inversion Principle

  • This is also known as DIP
  • Introduced by Robert C. Martin
  • High level module should not depend on low level modules. Both should depend on abstractions.
  • Abstraction should not depend on details. Details should depend on abstraction.
  • The interaction between high level and low-level modules should be thought of as an abstract interaction between them

Intention of usage

If you look at the traditional layered approach-

Presentation Layer => Business Layer => Data Access Layer

Here, the high-level module depends on the low-level module.

In order to resolve this coupling issue, we will be introducing an interface layer through which different layers can interact.

Business Layer => Interface Repository =>this will be implemented in Data Access Layer

Business layer would be communicating with the Data Access Layer via the interface.

This approach will help us to test each module independently.

Refer to the .NET Code attachment (DIP folder)

Adapter design pattern is one of the examples of DIP usage. We are not going to discuss the adapter esign pattern in this article.