📜 ⬆️ ⬇️

"Mamkin architect." Part 1: Ups and downs of software engineering

Good day, dear readers of Habr. I present to you the series of articles "Mamkin Architect". This series of articles is inspired by Eric Evans' Object-Oriented Design (DDD). Structuring of complex software systems. In it I will try to reflect my personal opinion regarding the construction of flexible architectures. Along the way, I will explain how this will be useful for managers and will help developers to strengthen the basic concepts.

image

This article focuses on the "creative rise", "creative recession" and the poker concept of "tilt". The latter perfectly reflects the state of the developer in those or other states of the objective model in the context of software architecture. Opus is useful:

  1. Managers solving issues from developers like “let's dig in and redo everything”.
  2. Application developers who will be interested to look behind the encapsulation armor of a carefully constructed (or house) subject model in its conceptual form.
  3. Architects or system designers will be interested in my experience in introducing, supporting and retaining a subject model in conceptual contours.

So, what is the creative rise?


Creative ascent is a psychological concept, primarily related to the qualitative leap of the program. In simple terms, it is a wavelike feeling of satisfaction from the work done. A qualitative leap is achieved by refactoring. Non-technical experts explain what exactly the developers understand by the definition of "need to refactor."

To begin with, we will quote from Martin Fowler’s book Refactoring. Improving existing code ":
“Refactoring is the process of changing the software system in such a way that the external behavior of the code does not change, but its internal structure improves. This is a way to systematically bring the code in order, in which the chances of new errors occurring are minimal. In essence, when refactoring a code, you improve its design after it is written. ”

Complicated? Then we break refactoring into three main subspecies, namely:
')
  1. Nano refactoring happening all the time. The most common form that is not used by all developers. But there is a fairly large percentage of people who can change the program at a very high level. Most often, nano refactoring is aimed at modifying methods / functions that are not of great value for a subject model. Example: splitting a large method into smaller functions without side effects.
  2. Micro refactoring, aimed at changing the logical structures within the system object. It is often used with the advent of new knowledge about the subject model, but sometimes the motivation is deeper than just creating a readable code. The general meaning is as follows: to split the process of movement towards a deep, loaded with meaning, models on the stage. Such refactoring is convenient in that it does not “freeze” the development process. Its main goal is to help the developer to understand not only the principle of operation of a specific object, but also why the object does what it does. This understanding is also awakened by specialists in the applied field, generating a single language in the team.
  3. In-depth refactoring is the most complex, aimed at radical changes in the subject model. He is motivated by a deep understanding of the subject model. Its direction is the most dangerous, since it has a radical impact on the entire software product. An example from real life can serve as an ordinary car, whose engine was changed to a rocket engine. A simple machine cannot call such a technique any more, and it will no longer perform its main functions.

As you might guess, one type of refactoring comes from the other on the principle of communicating vessels. But what happens when the last vessel fills? You can imagine some fundamental shifts of the system as a whole, for example, when a liquid is spilled. In fact, overflowing the last vessel is an impetus to in-depth refactoring. The conceptual model is changing, the project architecture is not. At this point, the software product begins serious problems. The system model no longer corresponds to the software architecture expression. Many companies try to postpone this moment, periodically applying refactorings of a higher level. The reason for the tactics is simple: in-depth refactoring will simply stop the plant.

By applying higher-level refactorings, we can substitute a bucket for imaginary vessels or wrap them in a bag. If you take all these "gags" and multiply by the time and classification of specialists, you can get an unmanaged system. The latter closes on several members of the development team. Knowing these subtleties, you can even arrange sabotage without fear of dismissal. Several dedicated understand the principle of the system with all these packages, chewing gum, launchers and other things. Undoubtedly, for such people a cauldron in hell is ready, but we shall return to this later.

Regrettably, sooner or later, the critical mass in the last vessel will reach the tensile strength of the vessel itself, causing it to burst. At such times, refactoring usually does not end there. It’s easier and cheaper to rewrite everything from scratch. Therefore, let us return to a more optimistic model.

The creative rise is preceded by a qualitative leap in software. Before a qualitative jump in a software product, in-depth refactoring takes place, etc., up to nano refactoring.

An example from a real project


Participating in one of the projects, we spent about two months over refactoring the system for creating meetings between people. It was superficial and only eliminated the hard consequences of outsourcing. Having decided on the readiness of the system for further development, we faced a number of problems. I exaggerate a bit the complex algorithm of the recommendation system, but the meaning will remain the same.

In fact, the recommendatory system was supposed to offer users for a hike in the forest, walks to drinking establishments, and so on. It is worth noting that I am not an expert in this field. The task appeared to improve the system by adding additional criteria. Since the recommender system was part of the domain model, it turned out to quickly find the right specialist. For a couple of meetings, he helped to clarify the subtleties of the system and there were no unresolved issues.

The model we developed was good, but ...


At first, we were optimistic. For more than three months, we managed to work out the software architecture. Then she was “synchronized” with the subject model.

Clarifying the selection rules, we made changes to solve problems in the current mode. But with the addition of each new selection criterion, the complexity of the architecture also grew. It was not possible to quickly reach stable and reliable functionality.

More we began to worry about errors in rounding calculations. This could define users in groups with which they are not related. Of course, these errors were insignificant from one point of view. But from the point of view of the accuracy of the “recommendation system” they raised certain questions. At this point, we began to suspect that these inaccuracies were not just cosmetic problems, but symptoms of fundamental problems with architecture.

Jump


Suddenly, we came to understand the problem and its solutions. In our model, users and groups were connected in a manner inconsistent with the real state of affairs. This discovery had a wide resonance. We made an appointment with the subject matter experts, with the support of which we drew a new model on the board. It is worth noting that the details of such have not yet crystallized, but we already knew what a new feature is crucial for the model. The definition of a user's group could occur regardless of their preferences. Funny, but in the framework of this software product - fair. Having made a similar conclusion, we proceeded to the passage of various scenarios of the behavior of this model and its vulnerability.

Now the groups were formed by shares, we introduced the concept of "shares" in our common language. The need for the concept of "group" has disappeared, since the formation has already taken place according to the interests of the user. We began to cultivate a common language of terms, which made it easier for us to communicate with subject matter specialists at meetings. Everyone clearly understood the essence of the conversation, because we operated on the terms of the subject model. And she fit perfectly on the architecture of the application.

Sober look at things


Do you think that at this moment we felt great? Nearly. Yes, the hypothetical implementation of the domain model fits perfectly into the new architecture. But for the project were established tight timeframes, in which we hardly fit. The main feeling that I personally experienced at that moment was fear .

Paradigm of refactoring - movement in small steps and the need to constantly maintain the software product in working condition. But refactoring our code will require deep refactoring. The software product will not only have to be temporarily disabled, but also postpone its release. We will also lose working intermediate states. The product history is broken down into “before” and “after.” Our team saw small improvements that could lead to some positive results. But this did not bring us closer to the conceptual integrity of the system. After a couple of technical meetings, a sequence of steps was revealed that could prepare the modules for the transition to a new conceptual model. But they could hardly keep their performance. Needless to say that in the heavy heredity there were no automatic tests? We could not guarantee the backward compatibility of the modules corresponding to the new and old subject model. Failures and errors would be unequivocal. Along the way, new efforts were required to introduce this model, and we were already exhausted by mouse fuss.

Smoothly, I began to realize that my attitude towards the project was becoming mediocre. It became difficult for me to talk in terms of the old model. Later it turned out that I was in a state of tilt. This term was introduced into my everyday life by a friend who actively plays poker and takes top places in tournaments. He explained the following to me: “During tilt, you are no longer guided by your mind, but by your emotions. For a poker player, this is simply unacceptable. ” Having made an analogy, I realized how much I display unnecessary emotions about global alterations.

It was at this point that the development team met with the manager, which I will never forget. Our leader was a smart and confident man. He asked us a few questions. I cite an exemplary dialogue in which P is the leader, K is the team, and T is the leader of the team.

R .: How much will the new model be implemented in order to return to the current functionality?
K .: About six weeks.
R: Is it possible to solve the problem without such global changes?
K .: Yes, but there are no guarantees.
R: Is it possible to release the next version of the program if these changes are not implemented now?
K .: Without introducing changes, the forward movement will slow down greatly and it will be more and more difficult to make new adjustments. The movement of the project will stop after installing the entire code base.
R: Are you personally sure that redoing everything is correct?
T .: We know that the program is now loose and its efficiency is hanging by a thread. If we have to, we can do it the old-fashioned way, because we ourselves are tired. But it is better to say “yes”, insisting on a simpler solution, better suited to the purpose of the project. If we talk about the prospects for the development of the project, then to introduce a new model is less risky.

Then the head approved our actions and noticed that he would close us from all attacks from the customer. We rolled up our sleeves and finished everything in five weeks. There was a disproportionate amount of work, but we became a real family. The implementation went quite smoothly, perhaps, our modular strategy affected.

Reward


At that moment, we felt a real boom. My nervous breakdown was postponed indefinitely. The implementation has become more meaningful and complete, there were no problems with the recommendation system. With the rest - too. All modules worked in the same architecture, reflecting the subject model. We released the first version and were very warmly received by users. We were firmly on our feet, because subsequent versions were no longer a problem. The development of the model was accompanied by the development of a single language. For the third version of the program, everyone actively applied the terms of "our" language. Marketers intensively used it in communicating with potential investors, explaining the possibilities of the program.

but on the other hand


On my way there were projects whose leaders did not have the courage to “step into the unknown.” Motives were different, starting with mistrust and ending with “postpone for later”. But, how much rope does not curl, the critical mass will increase. Along with her comes tilt, and behind it - unsupported program. These are signs of global changes that are not always pleasant and painless.

Finally


It is very difficult to advise something, because everything depends on the project. Do not try to artificially cause a qualitative leap, it will only freeze the work. Jump potential usually occurs after a refactoring cascade. Then comes the epiphany, a new vision of the model and its display in the software architecture. Most of the time, it is minor changes, preparation for a jerk, and a set of critical mass.

While preparing the ground for the jump, focus on acquiring knowledge about the subject model and cultivating a single language. "Feel" the concepts of the subject area and express them in the model in the most explicit form. Improve the architecture of the program, making it more flexible. Distil the knowledge of the model, emphasize the most important and dispute. Improve understanding and visibility. These factors contribute to a qualitative leap. A qualitative leap has a beneficial effect on all branches of software development. Developers become more confident in their program, managers sensibly evaluate the tasks. Peace, friendship gum!

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


All Articles