SOLID Principles

James
4 min readMay 8, 2018

--

My time in my programming cohort is coming to an end. Tasked again with another blog post assignment, i’ve decided to write about something I need a better understanding of. SOLID principles. During the cohort we briefly discussed these principles, mixed in with the other half dozen topics we would go on to discuss that week. The pace of the cohort makes it difficult at times to fully digest new ideas, so I find myself revisiting ones that sparked my interest the most, or ones I did not clearly understand so quickly. This was a topic I feel like I needed to review.

In object-oriented computer programming, the term SOLID is an acronym for five design principles intended to make software designs more understandable, flexible and maintainable. Though they apply to any object-oriented design, the SOLID principles can also form a core philosophy for methodologies such as agile development. Let’s take a close look at each one of these principles.

S — Single Responsibility Principle

A class should have one and only one reason to change, meaning that a class should only have one job, one responsibility.

This is important because when requirements in your code change, your code has to be restructured or modified. If your classes have many responsibilities these modifications can be extensive. The single responsibility principle makes it easier to implement changes in your code moving forward.

O — Open-Closed Principle

A class should be open for extension but closed for modification.

This principle is the foundation for building code that is maintainable and reusable.

Robert C. Martin

. Open for extension

As requirements change we should be able to make the class behave in ways that adjust to those requirements. This would be extending the functionality or behavior of a class. Remember we do not want to modify the code to heavily for the same reasons as we want a single responsibility — the changes would be too extensive.

. Closed for modification

This essentially means that the source code for a class is ‘set in stone’. Meaning we should not introduce breaking changes to the functionality of a class. The refactoring process would be arduous.

In order to effectively achieve this, we would use abstractions. A popular example i’ve seen to describe this would be using shapes. If we wanted our system to work with shapes, we would probably have classes like circle, triangle, rectangle, etc. To make new shapes, it would be best to implement a shape interface or class instead of calling upon one of the lower level classes.

L — Liskov Substitution Principle

The Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called (strong) behavioral subtyping, that was initially introduced by Barbara Liskov in a 1987 conference keynote address titled Data abstraction.

The basic idea behind the principle is that every subclass/derived class should be substitutable for their base/parent class. A subclass should override the parent class but only in a way that does not break functionality. To riff on the shapes idea in the previous principle. Let’s take two: rectangle, and square.

If we have a rectangle class and square class to extend it, this could be problematic. Both shapes have a width and height, if we were to create methods to set these, their methods would differ. By definition a square is a rectangle, just with an equal height and width. So the methods that control the width and height of the square would be different than those of the rectangle. We do not want this methods to behave differently. So, in this example, we would not want to use the square class to extend the rectangle class.

I — Interface Segregation Principle

The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces.

This principle, much like the other SOLID principles, is centered around the separation of concerns idea. The idea is to have a high level of specificity regarding interface usage.

A popular example used to describe this idea uses the animal kingdom. Let’s say we have an Animal interface. On that interface we have two methods: eat, and walk. This is not an ideal abstraction because not all animals walk. Some fly, some swim. It is a better idea to create methods like: canWalk, canEat. Abstract these methods down into roles. That way our new animal is composed of its necessary roles, and not coupled to the roles in which it has no use for.

D — Dependency Inversion Principle

Entities must depend on abstractions not on concretions. It states that the high level module must not depend on the low level module, but they should depend on abstractions.

This concept is the most tricky to me, but I found a good example that allowed me to better understand it.

When signing up for a new account , application, or service on the internet now, it is fairly common to be presented with options in order to authenticate yourself. You’ve downloaded a new app, or extension, when signing up it prompts you to sign up with an account. These accounts can be with Google, Facebook, Github, LinkedIn or something similar. These accounts would act like an authentication service. You could write code for each authentication service, or you could create an interface for all authentication services. The latter allows our code to be more reusable and more flexible. We can create new authentication services with ease without changing the integration logic of each.

--

--