Photo by Gigi on Unsplash

Why do we want to be SOLID?

All of us want to surround ourselves with solid things. We believe that if something is solid, it is better, more durable and will last longer. The same situation applies to programming. We expect the reliability of the programs in carrying out the tasks entrusted to them. The programs are written by people, at least the most of it and here developers strive for high quality work and expect these programs to do their job.

The implementation of specific tasks by the program/code can be achieved in many ways. One method is to use the SOLID principles. Thanks to them, our code becomes clearer, easier to understand and more flexible during development. This is particularly important when the team cooperation on the project is large or scattered across several countries as in the case of Netcompany.

Netcompany provides IT solutions for both large enterprises and governments

My work involves, among others things, designing and implementing software solutions. I started working with a team located in Oslo, on an international project applying these principles. Thanks to SOLID, I could quickly learn and start the development project, written by the Norwegian team. Returning to the topic, I will describe everything I know about SOLID recommendations.

SOLID consist of 5 principles:
· Single Responsibility Principle
· Open Closed Principle
· Liskov Substitution Principle
· Interface Segregation Principle
· Dependency Inversion Principle

Single Responsibility Principle

The principle of single responsibility obliges us, developers, to ensure that a class only have a single responsibility. It may sound like a simple task. The truth is that this is one of the hardest rules to follow. During the development of the application there are temptations to add something to a class, not necessarily related to its main purpose.

Below is an example of two classes: Document and ConvertToBase64.
The Document class contains only file information (name, create date and content).

The ConvertToBase64 class is only responsible for converting the above document.

The Document class could have the ConvertDocument function, but then it would be responsible for itself and the conversion process. The primary task is to store information about the document.

Open Closed Principle

The term “open” means that specific classes/modules/solutions/components should be open for extension, but also closed for modification. You should understand, that the extension should not change existing logic. Thanks to this approach, code’s quality the will be higher and potential problems after extending should affect only new functionality. In short, it will not affect the operation of a stable system.

Let’s assume that we have a new requirement to store its author on a document. The Document class needs a new attribute: “author”.

The constructor class has been overloaded, so as not to change the code or affect reference in other modules.

A new ConvertAuthor function has been added to the ConvertToBase64 class:

Everything looks good, but we use the same code in two functions: Convert.ToBase64String. The code can be extracted without changing the logic.
It can be done in this way:

Liskov Substitution Principle

This principle shows developer the way in which system can be expanded. If two or more classes have elements in common, they should be separated into the base class. At same point, other components of the system will use the base class.

Field sourceDocument was extracted to base ConvertBase class. The ConvertToBase64 class inherits from ConvertBase class.

Now, developer can create other class: ConvertToPDF and inherits from the same class ConvertBase.

Inheriting from this class, the developer must remember not to change/overload its result. Calling the same function in a parent class must always give us the same result.

Interface Segregation Principle

The interface segregation guideline requires us to eliminate overloaded interfaces. The individual logical functions should be extracted to separate interfaces. However, classes that need to use these functions should not have references to classes, but to interfaces. This approach enforces us to create lightweight, interface focused on one task.

Take a look at simple IDocument interface:

It has been implemented into the Document class:

Dependency Inversion Principle

The principle of reversing dependencies.

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.

In short, we should use the interface in property declarations so that classes don’t depend on each other. By following this rule, one can easily swap mechanisms without modifying dependent classes.

For example in the above example, the Document class was replaced by IDocument interface:

In my opinion, a good example can be access to the database. Think about the fact that one day you will need to replace the engine with a different one. If you use interfaces, you can prepare a new solution with interface implementation. The next step is just changing the old engine to a new one.

Summary

I have briefly presented the principles behind the SOLID abbreviation.
The recommendations above were written by Robert C. Martin, who is a software engineer and has been involved in programming since 1970.

You can follow/contact me through this link: Daniel Jankowski

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store