This article is basically a free retelling of a fragment of Eric Evans's Subject-Oriented Design, in which he discusses the Separate Ways and the Bounded Context.
Suppose there is the following situation: several development teams are working on the same project, but they solve different tasks. For example, the project is a chip designer, and the first team implements the chip ringing functionality, and the second one is calculating the cost of the chip.
Question: what is the best way to do - 1) allow both commands to “boil in their own juice”, having received two modules at the output, the code of which practically never intersects anywhere, or 2) to establish communication between the two commands, make them work together and get a single output monolithic system? There is no universal answer to this question (“yes” or “no”) and an analogy with the elephant and the sages will help us find the answer in this situation.

')
Here the elephant is a complex subject area, and the sages are programmers.
Six Gray-Haired Wise Men
Converged from different countries.
Unfortunately, everyone was blind,
But mind shone.
They explore the elephant
Came to Hindustan.
One stroked the side of an elephant.
Satisfied with that,
He said: "The truth is now
As day is visible:
The subject of what we call the elephant
Sheer wall! ”
And the third trunk in hand took
And shouted: “Friends!
Our question is much simpler
I am sure of it!
This elephant is a living being,
Namely the snake! "
Sage fourth grasped
One of the elephant's legs
And importantly said: "This is the trunk,
The picture is clear to me!
An elephant is a tree that blooms,
When spring comes! ”
Meanwhile the sixth of them
Got to the tail.
And laughed at that
As the truth is simple.
“Your elephant is a rope. If not
Sew me mouth! ”
And as you know, the sages
Inherent stubborn temper.
Unleashing the dispute, they reached
Hardly any more than reprisals.
But the truth, no one knew
Although he was somewhat right.
If the subprogram of the team of programmers (sages) interacts with a specific part of the subject area (with the legs of an elephant), then it does not need to know the entire subject area (elephant) entirely. At the same time, if they simplify this part of the subject area, throwing away all unnecessary (turning an elephant's legs into trees), then they will receive a code that anyone who has little knowledge of the subject area can understand (does not know what an elephant is). In addition, if the subject area is too complex, then when you try to clutch the immense, the programmer will fall into a cognitive stupor and the speed of development will drop by an order of magnitude. But, on the other hand, with this approach, the interaction between the individual parts of the program is complicated.
Let's compare both approaches. So, the advantages of large contexts (monolithic systems):
• various user operations are interconnected more smoothly and naturally, when as many different objects and operations as possible are covered by one unified model;
• it is easier to understand one coherent model than two different ones and the level of display between them;
• translation between two models may be difficult (or even impossible);
• common language stimulates a clear interaction in the development team.
Benefits of small contexts (many dissimilar modules):
• reduced costs of communication between developers (because the communications themselves are less);
• CONTINUOUS INTEGRATION (CONTINUOUS INTEGRATION) is easier to perform in small groups with small code bases;
• in larger contexts, more versatile and abstract models may be required that require infrequent developer qualifications;
• small models can serve special needs or conform to the jargon of specialized user groups, as well as highly specialized dialects of the UNIQUE LANGUAGE (UBIQUITOUS LANGUAGE).
It should also be noted that theoretically snake, trees and a rope can evolve into an elephant. If, for example, the specification of the program changes and it turns out that the elephant can walk, then the trees may well turn into legs. However, not all so simple. The case where parts of the domain do not intersect anywhere is idealized, in practice, most likely it is not. Suppose two teams of programmers work with an elephant's trunk, but the first team is interested in the fact that the trunk has the properties of a living being, and their trunk is a snake, and the second team is interested in the ability of the trunk to splash out water, and their trunk is a water hose. Over time, by chance, both development teams realized that the snake of the first team and the hose of the second described the same thing, after which the second team decided to replace the hose with a snake-spitting water. And this will require a two-week refactoring. From my own experience I’ll say that no one will give you two weeks to do what’s not clear, unless the project has begun to sink to the bottom under a load of technical debts, but even in this case, you’ll be solving two weeks more pressing problems than turning a hose into a spitting snake . Thus, in the realities of the Russian development, if you initially do not start moving in the direction of a monolithic model, then it will be almost impossible to switch to it, while avoiding solidity is not a problem.
If you chose the path of many non-interconnected modules, then remember the following proverb: "If three teams of programmers develop a compiler, then they will get a three-pass algorithm at the output." Beware of this. The program architecture should reflect the subject area, not the internal structure of your company!
PS This article was born as a response to a small holivar in
this article . If you are interested in examples from real life, I recommend reading the article
Unrestrained violation of the principle of multilevel .