SOLID Principles Explained Simply
By: Ariel Jakubowski
Tags: Coding, Programming, Software Engineering, Software Development, Solid

The SOLID principles are fundamental principles of programming that help keep code organized and efficient. SOLID is an acronym representing five principles of object oriented programming. The acronym is as follows.

The principles behind the SOLID acronym

Single Responsibility Principle

The Single Responsibility Principle states that a class must have one and only one reason to change, hence a single responsibility. This principle involves cohesion, which in Software Engineering means the degree to which the pieces of functionality of the source code in a module or class are related.

For example, let’s say we were building a productivity app complete with a to-do list, a schedule, and a timer. We could make our entire app in one class but this would not be very well organized or efficient and would group together a lot of pieces of functionality that would be very different from each other. Instead, it would be better to create separate classes for our to-do list, our timer, and our schedule. We would use each class to control the information that is relevant to that area of the program’s functionality. We would not put a function or method called setTimer in the to-do list class because that is not the most relevant area for that type of functionality. This function would instead belong in the timer class and would have greater cohesion with the functionality in the timer class.

Open/Closed Principle

The Open/Closed Principle states that the behavior of a class should be able to be extended without being modified. In other words, a class should be open for an extension but closed for modification.

For example, if we wanted to create a program that found the area of a shape, we could start by creating a function that would check if a shape is a rectangle or a circle and then determine the area accordingly. The problem with this is that if we wanted to find the area of a different type of shape then we would need to modify the class. By the Open/Closed Principle, it is better to instead make a separate class for each type of shape, complete with its own method or function for determining the shape’s area. This would leave the program open for extension in the form of additional classes being made to expand the functionality of the program but the program would be closed for modification because the existing code would not need to be changed.

Liskov Substitution Principle

The Liskov Substitution Principle states that subtypes should be replaceable by their base types. A motivation behind this principle is to ensure that inheritance is not being used when it is not appropriate for the code. Although it may be easier to extend a class to a subclass, if the functionality of the class will not be used or will be overwritten by the subclass then inheritance should not be used.

Interface Segregation Principle

The Interface Segregation Principle states that multiple specific interfaces are better than one general interface. This principle involves the cohesion of interfaces and the benefits of having few behaviors. By theInterface Segregation Principle, the dependency of one class on another should be the smallest possible interface.

The idea behind the Interface Segregation Principle is that if code implements an interface then it should use everything in the interface and code also should not rely on methods it does not use or should not have access to. The solution to this is to keep interfaces small in order to minimize interdependency.

Dependency Inversion Principle

There are two parts to the Dependency Inversion Principle. The first is that high level modules should not depend on low level modules; they should both depend on abstractions. The second is that abstractions should not depend on details, details should depend on abstractions.

The first part of this means that a high-level module should not be doing low level work. An analogy for this is that the CEO of a company would not be making deliveries or taking customer service calls, they have their own work to do with a higher level. The same is true for modules and classes. Returning to our productivity app example, the class that renders the entire app and its high level components of the to-do list, schedule, and timer, should not be responsible for setting the name of a new event in the schedule. That is a job for a lower level component within the schedule class.

The second part of the Dependency Inversion Principle, to use abstractions over concrete details, helps to keep code flexible. The more information that is hardcoded in a program and the more concrete details that are used in code, the more rigid the code becomes and the more limited its functionality and uses can become. Such a lack of flexibility and code can leave it prone to errors and a limited or poor user experience.

Gain Access to Expert View — Subscribe to DDI Intel