Hello.
Week of articles on Habré dedicated to the PLO. This last article caused me a lot of emotions and, unfortunately, very bad emotions. I really did not like the article. Why? Because it conveys some negative emotions about the use of the PLO. Emotions are caused only by the fact that a person does not fully understand the whole power of the PLO and wants to convince everyone that PLO is evil. The saddest thing is that people begin to listen and throw horrible arguments that have nothing to do with reality. I think that such articles are contraindicated to students more than GoF, which I would give as soon as possible. :)
Let's start.
What is OOP. OOP is both OO programming and design. One without the other is meaningless a little more than completely. Created by OOP for designing / programming software products. Not for process modeling. Not for the design of protocols, namely for software products, for their implementation. To simplify a system that will implement a protocol or a business process or something else.
')
When you start using OOP, the first thing you need to do is start using object thinking. I once said that this is the biggest problem of the PLO, learning to think objectively is very difficult. And it is very important to learn to do this as early as possible (GoF with analogies such as bridge, designer, facade will help a lot with this). Using object thinking, you can easily design complex systems.
Using object thinking, you can easily solve any problem (it is very important that any design / programming problem, if absolutely any can be solved in principle) with objects and the interaction between them. Those. OOP without object thinking will not allow you to start using all the power and strength of OOP.
Let's go further. So, it is important for us to think objectively, in order to find the necessary abstractions of objects for solving our problems. If the analogies and abstractions are chosen successfully, then we see a very clear picture that allows us to quickly understand what is happening in the system. And here we begin to remember about inheritance and polymorphism. These two tools are needed for convenient system scaling without code duplication. But the strength of these mechanisms depends on how successful abstractions and analogies you have chosen. If your object thinking does not allow you to form a convenient decomposition of objects, then inheritance and polymorphism will not help you. Those. inheritance and polymorphism is nothing more than the tools that solve the problem of scaling the system.
How do these tools work? Yes, it's easier than steamed turnips, because it's all based on things we are used to. I love simple life examples:
1. Inheritance. There is a baker. There is an electric and gas stove. Your task is to simulate the process of cooking by the baker in each of the ovens. Solving the problem in the forehead, we will have a lot of code duplication due to the fact that the process of transferring food to the oven and the work with the ovens are identical for both ovens. But if we include object thinking, and recall the inheritance tool, we get something like the following (lazy to draw a diagram, sorry):
There is a stove (abstract stove). She has a behavior - turn on, turn off, increase or decrease the temperature, put something, get something, and the state - the temperature in the furnace is on or off. This is a great example of an abstract object in which the principles of encapsulation are respected (when implemented, I will definitely follow them). And there is a baker, a particular such baker Ivan. He knows how to work with an abstract furnace. Those. watch the temperature, turn it off, etc. did you understand. The power of inheritance is that we do not have to rewrite our Ivan for each of the furnaces, be it an electric or a gas furnace. I think it's clear to everyone why? It turns out that the tool is applied correctly.
2. Polymorphism. The furnaces work in different ways. Gas consumes gas, electric furnace - electricity. Using polymorphism, we easily change the behavior in the heirs of an abstract furnace.
3. Encapsulation. The main feature of encapsulation is that I should not know what is going on inside my oven. Suppose I do not call the method to turn on the oven, but I change its property to true. What happens at this moment? If the principle of encapsulation is not respected, then I will have to tell the furnace to start to consume fuel, because I turned you on Those. the baker knows that the oven consumes fuel, knows how the oven works. Or, for example, we cannot set the oven temperature below or above a certain level. If the principle of encapsulation is not followed, then we will have to tell the furnace to check the current temperature, will those go? Those. the baker again knows too much about the oven. Getters and setters are language tools that will help us easily implement state change tracking. Everything. If the getters and setters are empty, then this is necessary at my level of abstraction. Getters and setters - can not interfere with the implementation of encapsulation, the designer / programmer can crookedly implement encapsulation.
In this example, the level of abstraction is well chosen. All do their own thing, all three whales of the PLO work for glory. But if I choose bad abstractions, how a nightmare begins. And even there are
standards checklists that will help you to understand
whether you have chosen well the abstractions and whether your decomposition is correct in that direction you are going (SOLID).
Another began to add abstraction, as another pillar of the PLO. I think this is probably true, but it smells like CEP.
Statements about typing also hooked me. The fact is that there are no problems with whom you are currently working from the heirs. If at the current level of abstraction it is important for you to use the furnace, then it does not matter what it is. Are you getting a stove? Do you solve your problems? That's it ... Why do you think that this dynamic typing is not clear to me. Did you want a stove? Take it. Do you need electric? Well, sorry, gas will not work for you anymore.
The remaining examples, which were cited in the article that hooked me, are only examples of a disgustingly chosen abstraction and analogy within the framework of the task. Point.
Separately about DTO. DTO is a pattern. It allows you to create an object that will transfer information to another layer, another system, in short, it will transfer something somewhere. Why it can not be considered by me as an object for me is generally a mystery. Where is the contradiction then? Is the container only? So what?? This is an object within the framework of the object model considered by me at a given level of abstraction, where DTO is an object and part of the decomposition.
About languages, too, it is not clear what to say. I can design software using the object approach regardless of the language. But if the language does not implement the basic tools for working with objects, then it will be very difficult or impossible for me to implement the system I designed.
They also say that some things cannot be represented in the form of objects and their interaction. I am sure that it is not. Just need to choose the level of abstraction right. Whether it is the implementation of the protocol, the database access layer, plug-in connection, task manager, business process, business process design system Anything can be represented as objects and their interaction. Everything can be implemented as objects and interaction between them. Good or bad often depends only on your ability to think objectively.
Summarizing. If you do not understand the power of OOP, then most likely you need to develop object thinking.
PS In the comments to the last article, I clearly outran the stick when referring to some people. I apologize.