📜 ⬆️ ⬇️

SOLID

SOLID criticizes one who thinks he really understands OOP.
© Kuryashkin Victor

I am familiar with the principles of SOLID for 6 years, but only in the last year I realized what they mean. In this article I will give a simple explanation of these principles. I will tell about the minimum requirements for a programming language for their implementation. I will give links to materials that helped me figure it out.


Primary sources


He came up with the principles of SOLID Robert Martin (Uncle Bob). Naturally, in his works he covers this topic.


The book “Principles, Patterns and Methods of Agile Development in the C # Language” 2011. Most of the articles I have seen are based on this book. Unfortunately, it gives a vague description of the principles, which greatly affected their popularity.


Video site cleancoders.com . Uncle Bob in a joking way on the fingers tells what exactly the principles mean and how to apply them.


The book “Clean Architecture” 2017. Describes architecture built from bricks that satisfy SOLID principles. Gives a definition of structural, object-oriented, functional programming. Contains the best description of the SOLID principles I have ever seen.


Requirements


SOLID is always mentioned in the context of OOP. It so happened that it was in OOP languages ​​that convenient and safe support for dynamic polymorphism appeared. In fact, in the context of SOLID, OOP is precisely dynamic polymorphism.


Polymorphism makes it possible for different types to use the same code.
Polymorphism can be roughly divided into dynamic and static.



In addition to familiar languages ​​like Java, C #, Ruby, JavaScript, dynamic polymorphism is implemented, for example,



Principles


SOLID principles advise how to design modules, i.e. building blocks of which the application is built. The purpose of the principles is to design modules that:



SRP: The Single Responsibility Principle


A module should be responsible for one, and only one, actor.
The old wording is:


Often it was interpreted as follows: The module should have only one duty . And this is the main misconception when meeting with the principles. Everything is a little trickier.


On each project, people play different roles (actor): Analyst, Interface Designer, Database Administrator. Naturally, one person can play several roles at once. In this principle we are talking about the fact that one and only one role can request changes in a module. For example, there is a module that implements some business logic; only the Analyst can request changes in this module, but not the DBA or UX.


OCP: The Open Closed Principle


For software modification.
The old wording is: without modifying it .


It can definitely enter into a stupor. How can one extend the behavior of a class without modifying it? In the current formulation, Robert Martin uses the concept of an artifact, i.e. jar, dll, gem, npm package. To extend the behavior, you need to use dynamic polymorphism.


For example, our application should send notifications. Using dependency inversion, our module declares only the interface for sending notifications, but not the implementation. Thus, the logic of our application is contained in one dll file, and the class of sending notifications that implements the interface is in another. Thus, we can, without modifying (recompiling) a module with logic, use various ways of sending notifications.


This principle is closely related to LSP and DIP, which we will look at next.


LSP: The Liskov Substitution Principle


It has a complex mathematical definition that can be replaced by: Functions that use the base type should be able to use subtypes of the base type without knowing it .


A classic example of a violation. There is a base Stack class that implements the following interface: length, push, pop. And there is a descendant of DoubleStack, which duplicates the added items. Naturally, the DoubleStack class cannot be used instead of Stack.


This principle has a funny consequence: Objects that model entities do not have to implement the relationships of these entities . For example, we have integers and real numbers, and the integers are a subset of real numbers. However, double consists of two int: mantis and exponent. If int inherits from double, then a funny picture would turn out: the parent has 2 children.


Generics. , Shape Circle Rectangle. Foo(List<Shape> list). , List<Circle> List<Shape>. , . , , list , rectangle. list Circle.


ISP: The Interface Segregation Principle


Make fine grained interfaces that are client specific.


Java, C# . .


DIP: The Dependency Inversion Principle


Depend on abstractions, not on concretions.



? ? , . /, . .. , BD, , . , - — .


? , .. import, require .. runtime .


Logic, , . ISender, Logic. , ConcreteSender, ISender. , Logic ConcreteSender. runtime, , Logic ConcreteSender.


“ , ?”.


. , , , Postgresql, — ElasticSearch. . , , , .. , . , . , , , , .


SOLID , , — Agile Manifesto.


SOLID .


SOLID .


')

Source: https://habr.com/ru/post/348286/


All Articles