SOLID good to know…

Such things as SOLID It’s not uncommon to hear it in behind-the-scenes conversations or, even more often, during an interview. But partly without knowing exactly SOLID, every programmer unconsciously, but adheres to these principles when there is time)) But why is it important for us, as programmers, to know exactly the meaning of such abbreviations or, if you like, certain meanings from our profession. And everything is simple – it’s at least respectable, or rather, not knowing this is not respectable. (more about this in PS)

In particular about SOLID there is a lot already on the hub, but my article is more about the connection between theory and real life. In the last article, I tried to connect the patterns in people's minds with the code that everyone, as a Java Developer, works with every day. In this article, I already have the principles themselves SOLID I will try to connect with patterns, or rather with some of them, so that one with the other in your head comes into agreement and is not separate, since I believe that for them there is nothing closer to each other, and in general, a pattern is a principle and the opposite. SOLID This is a theory that in practice is often implemented in the form of patterns. This article is in some way a cross battle between patterns and SOLID principles.

SRP

Single Responsibility Principle – The principle of single responsibility.
Each object should strive for one area of ​​responsibility and one reason for existence, or, more simply put: each class should have one responsibility and therefore one reason for change.

Well, in my opinion, this is one of the most important principles contained in SOLID. Its reasonable use eliminates many headaches; those who work together on monster classes and puzzle over conflicts will understand me, but that’s not what the article is about.

Strategy. We put the implementation of a certain algorithm into a separate class and this gives us:

  • Our class and the algorithm itself have their own area of ​​responsibility and do not interfere with each other +1 SRP

  • If something needs to be changed in the algorithms, then we have no reason to change the parent class itself. In both cases, this is a plus to one reason for change. +1 SRP

Facade. So that your class does not depend on some external complex system, simply create a facade for this system, which gives us:

  • Our class and the actual work with the system have their own area of ​​responsibility and do not interfere with each other. +1 SRP

  • If something needs to be changed in working with the system, then we have no reason to change the parent class itself. In both cases, this is a plus to one reason for change. +1 SRP

DDD. Breaks the entire domain model into subdomains. Each subdomain has its own data model, the scope of which is usually called a limited context +1 SRP

Database per service. Each service has its own database for work, and each database has only one service for which it can be changed +1 SRP

CQRS. In simple terms, now we have logic for writing and reading data that exists separately and has different areas of responsibility.

OCP

Open-closed principle – The principle of openness-closedness.
Software entities (classes, modules, functions, etc.) must be open for extension, but closed for modification.

Strategy. We move the implementation of a certain algorithm into a separate class and this gives us: now there is no need to go into the parent class to add new logic. +1 OCP

Adapter. This pattern is intended to organize the use of object functionality that is inaccessible or undesirable for modification, and I have the feeling that this pattern was created to solve the problem of the lack of OCP in the code. Even if the system for which we are writing an adapter did not strive to be flexible for everyone, we will expand its capabilities without the need to go inside. +1 OCP

Decorator. We add additional behavior to the object without changing the internals of other decorators or the class itself. +1 OCP

In general, it is worth noting that the patterns that help us adhere to this principle are a carriage and a small cart: Template Method, Bridge etc. +10 OCP

LSP

Liskov Substitution Principle – Barbara Liskov's substitution principle
Objects in a program must be replaceable with instances of their subtypes without affecting the correct execution of the program.

Template method. It was strange not to mention this pattern when analyzing this principle, since both this pattern and this principle make full use of the possibility of polymorphism.

Decorator. When implementing this pattern, you must also adhere to this principle, since each plug-in decorator implies adding additional behavior to the object, and not changing its logic beyond recognition, so it will be difficult to track where everything went wrong +1 LSP

It is worth noting that specifically with the complexity of implementing this principle in life, excessive complexity or, in the end, the careless attitude of the creators of certain libraries, we ourselves, as Java developers, often encounter exceptions associated with the “unscrupulousness” of developers.. .

  • UnsupportedOperationException – then when we receive a list, for example, and without suspecting anything, we try to add a new element to it. Yes, many interface implementation methods Listwhich returns, for example, the same List.of(...) throw this exception

  • PSQLException – when we, for example, call a method execute (String sql) our Statementand it in turn is the implementation PreapredStatement postgres drivers.

But it is worth noting that the examples above are not entirely bad, no, it is more or less justified, LSP violation is more critical when we not only encounter an exception in the source code or in runtime and solve the problems, but when we do not immediately encounter obvious changes in the logic in the contract methods implemented by some class, but it, in turn, has them, and the problem here is that the developer of this code did not notify us about this in advance. -1 LSP

ISP

Interface Segregation Principle – Interface separation principle
Clients should not depend on methods that they do not use; in general, this is about proper separation of interfaces.

Backends for frontends. In addition to all other possibilities, this architectural pattern allows us to collect a request for a specific client in the form necessary for it, thus we can not make a common API for all clients, confusing them or limiting them in some way, but implement our own version for each, dividing everything as needed +1 ISP

DIP

Dependency inversion principle – Dependency inversion principle
Modules at higher levels should not depend on modules at lower levels. Both types of modules must depend on abstractions. That is, abstractions should not depend on details, details should depend on abstractions.

Creating abstractions is one thing, but direct concrete initialization of an object is another, that is, IoC, and here we also should not depend on the details, that is, we forgot about the keyword new

IoC. Inversion of Control is a kind of abstract principle, a set of recommendations for writing loosely coupled code. The essence of which is that each component of the system should be as isolated as possible from the others, without relying in its operation on the details of the specific implementation of other components. +1 DIP

Factory method. The creation of one or another object is taken outside the class, thereby freeing it from one or another implementation +1 DIP

Facade. We transfer the logic of the operation of a certain system to the appropriate class and get – our module does not depend on details, that is, it is not related to the complexity of a particular system, and if it depends, it only depends on the abstraction of the facade +1 DIP

Observer. We implement a mechanism for the class that allows an object of this class to receive notifications about changes in the state of other objects and thereby make the connection between objects loosely coupled and less dependent on other classes (abstractions) in principle +1 DIP

PS

Why is it so important to know this?

Once I was walking through a beautiful European city, I was admiring it for the first time, but at some point I noticed one man, blond and with clear blue eyes, who was clearly watching me with open surprise, and in particular, he was attracted by my outpourings of everything those around me, or rather, well, as will be seen later, their form. This did not last long, and at some point he appeared next to me and, having greeted me in English, asked me if I was from Russia. To be honest, I hesitated a little, since my English, both then and now, gives me a lot of inconvenience in a live conversation, but I was able to decipher a more or less simple question and answered or even nodded in agreement. He smiled and answered: they say, so do I, and moreover, he said that he is Russian. After these words (of course, I had to think a little), I also smiled in response and was glad, hoping that at least some of the words I could afford in Russian, and after thinking a little, I asked in Russian: ah, how are you? Well… here, on the other hand, the answer forced itself to wait, but still after two seconds the person answered that he did not understand me at all and did not speak Russian at all. I hesitated a little (I also needed to understand that he did not understand me), and I reformulated my question in English and the interlocutor, in turn, answered: they say that it’s not very good, but I kindly asked what happened, and he answered something It seems like the day was not going well from the very beginning. I answered with a sympathetic look that I was sorry and that everything would work out (I can do this) and after that I decided not to continue the conversation since we had nothing left to talk about, which is exactly what I did then, shaking his hand and quickly leaving.

Why am I doing this, you ask?! Let's go back to that man, why do you think I didn't want to stand with him any longer or continue acquaintance, although his joyful face when he mentioned that I was from Russia made me happy?! I’m a sociable guy, and I would be pleased to hear my native speech, but… It turned out that the person in his entire conscious life did not bother to immerse himself even a little in his native language (although he was able to hear me among the crowd) before shouting: I’m from Russia… and so on. You have to understand me, I have nothing against his national identity and I'm not saying that he is not who he claims to be, but… it's just not respectable, guys. Doesn't he know what it is? how are you ? No, he knows how to ask a person about his affairs, and knows how to say from the heart about his affairs in our own way: Not good. Also, knowing the same words will not make him Russian and will not instill in him a love for everything Russian, not at all, but what is important is a form that will help us share ourselves and other people better with who we imagine ourselves to be.

It’s the same in programming, it’s not enough to say that you’re a programmer, there are sooooo many things that don’t make us programmers in practice, but just like that, casually, in a relaxed mode, in a conversation with colleagues, it’s worth answering something regarding the question once, well, for example, oh SOLIDor can even express his personal special opinion on this matter – Well, this is solid, maybe a little, but SOLID!

The analogy with language is not so far-fetched; in our rapidly changing world, in the conversation of IT specialists, the more and more there are names of private solutions to some problems that quickly become standards or the same abbreviations from them or other concepts, and it is no longer enough to know the solution, term or its meaning , you should also know his fashionable abbreviation and the sidecar concepts that he carries with him.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *