I think the answer lies in the question. Because they are already abstractions. And the programmer can do as he thinks best. At least who created the initial model can.
Abstract mechanisms or models
It is beautiful that you make a game where you have total control over what will happen, so control the domain. You might even decide not to put something in the template if it hurts you in something in the code.
What’s more, games tend to have little or no maintenance in production. Once it launches is ready and no more talk about it. Even a new version tends to be another code, even if it takes advantage of something from the previous one, it is not compatible. Wrong models don’t cause future problems. But that’s not the biggest advantage.
In game it is all very simple, the soldier is not a soldier in fact, it is an object that is known to be an almost arbitrary idea of what a soldier is, he does not need to do soldier things, he needs to do one or another action that the game defined what the sole does. Still may have complications, see the comments below.
In GUI you establish which abstract objects you will have, how they should behave and how they evolve (very little).
Rust is not OO. Try to make GUI with it, it’s a headache. Some say it’s better, but Guis do not thrive on it, the reuse is very complicated.
When you deal with a domain based on functions of the operating system or database, which are mechanisms, how do these things change? They hardly change because it’s all about thinking so as not to change, consumers are other codes that need stability. And when it fails and discovers that it was very wrong, it is simple to solve, make another and keep the previous as legacy.
An encryption system doesn’t have much to invent. An internal control of the system, usually does not move, very little authentication, even if it needs to avoid making fundamental changes and even so the use is usually optional.
All above mechanisms, all made to stay more or less frozen.
Note the difference between the database mechanism and the domain model that has built a specific database.
Real world domains
Now it goes to the real world, in general business issues that change almost every day, by force of legislation, updating technology that is not of computers, it is of the industry that is working, of general practices, of market, what you think happens with its model?
Fallacy of the domain specialist
Moreover, who defines what this model looks like? In the examples of the mechanisms you see that it was experienced engineers who made the model, passed through the sieve of many people or at least the objects were too simple. All very stable.
In business you don’t usually have a person who understands everything as that domain actually is. And even when they understand they can’t always predict the future.
That’s why I laugh when DDD promoters talk about "domain experts". This is usually a figure that doesn’t really exist. It’s a lot of people trying to hit something, and they don’t usually know what they’re doing. They deal with it every day and can’t make a definition of what every thing is, what the limit of every thing, what that bounded context. People try to guess. Sometimes it works, but not always. Of course there are people who do it a little better, but a model a little better and a bad has a very small difference, and a very large distance to the perfect model that is needed (perfect is not the same thing as definitive).
Complexity of the real world
Have you ever seen someone teaching OOP with a real world example? With all the complexity where the Animal
deals with everything an animal should handle in a system? If they show the thousands of classes needed to do this right everyone gives up.
You get to be required to put mechanisms that allow the object to evolve better, getting complex.
Mechanism here is something that does not matter for the domain, just so the software can organize the domain.
Even if you do a good abstraction, a proper encapsulation, and we’re even going to take away the question of inheritance, which is another thing that’s very complicated because it engages, yet it needs to have too many small objects to make up the main object. So far it’s a lot of work but it might not be a big problem because you did the right thing at the beginning of the paragraph. But at least part of this internal capacity of the object ends up becoming contracts of the object and something public, every consumer of it needs to know that. Even in some cases, even if it is by a passing parameter you need to know some details that do not seem to be so public, which is abstraction leak.
Change is the only constant
Sooner or later you will discover that something has been ill-defined and now create a working monument to set to work according to a change that happened in the real world.
When you model something fixed and abstract the object is that, it’s easy to see what it is. When you model business rules it becomes obscure, difficult to see and a change can invalidate that model if it wasn’t very well thought out. What is worth today may not be worth later. The comments below show that even in cases like this it can be difficult to make right.
When you model a business rule you try to get right what issues linked to that real-world object (which is not always an object at all) should be part of the computer world. And just some objects don’t even exist in the real world, but are needed in the computational world. Perhaps the secret of every answer is here. Abstracting the concrete is very difficult when the object must know everything it is capable of.
In the real world the object always has all the capabilities it needs and humans can’t get it right in almost every situation. It’s too complex for a human.
Isolating behaviors makes composing easier
If you abstract whole numbers, do you know everything it can do? In practice you know almost nothing, most, if not everything, of what may happen to it will be defined away from it, not object oriented, and it cannot be extended, it becomes much easier.
If you prepare too much for these changes, the system becomes too complex without bringing any concrete benefit to the business (it was only to facilitate a potential maintenance). If the system is very simple it needs a lot of effort for maintenance. You never get the point because you can’t predict the future and what parts of the object you didn’t model will be needed later.
In systems where behaviors are more isolated it tends to be easier to make these changes. The object is much simpler than done thinking OO and has less room for error and more flexibility by having more interchangeable things.
In general mechanisms do not possess much inheritance or have simple and obvious compositions. Inheritances are simple and fixed and in general is because of reuse.
What is the solution to maintain the sanity of business rules models? Adopt a lot of Pattern design Even if you don’t have to, but you’re gonna need it later. If you don’t adopt right away, the contract for that object may need to change, and a changing contract can go viral.
And I speak of contract in code or tacit contract. In the comments below I speak of it. OO works best in language with full freedom of how to model the object, to the point that it slows everything down (that does not matter for some, the language that people most use that approaches it is Ruby, tragic of slow) and less robust and the code has to be controlling every kind of problem that may appear, and there is testing, there is coverage to get close to something reliable. There often gets so complicated that the staff prefer one framework that worsens the bad indicators, but that makes it easier to achieve a better result.
Fallacy of decoupling
If you follow what people say to do, it becomes crazy. Imagine an object that is a product. It can change all the time. You can adopt whatever technique, a new field in it will force the entire system to be modified, unless you make a mechanism that tries to "guess" all possible behaviors and perform, probably with reflection. It may work in some cases, but it gets very complex and not at all efficient. And at some point it won’t work well. Everything will have to be done thinking about this mechanism and maybe the object is not ideal to do this.
Maybe the behavior should be the center of the issue here, you change the field and do not need to worry about the database, with the basic model, with the screen x or y, with a certain processing, etc.
Often to try not to leak the abstraction, which in practice is impossible in all cases, it is necessary to greatly increase the complexity of the whole by threading auxiliary mechanisms. And some will say that just the fact of having to deal with mechanisms that are not of the domain is already a leak.
Completion
How many times have I seen people try to model the domain well and create a Second-system (see comments below). It has object that has more complexity to its own complexity management than what it should do.
And how many times have I seen developer talking to the user that you can’t do what he wants. But in the real world it does. It doesn’t match the template he created.
Maybe the summary is:
Walking on water and developing software from a specification are easy if both are frozen.
- Edward Berard
Mechanisms have frozen specifications, business does not.
I don’t think it matters much the domain, the important thing is to know what to do, regardless of what it is. Rules won’t help much, but rules are more easily applied to mechanisms.
I love the quote
– Jefferson Quesado
It would have an example of mechanism?
– Piovezan
And what is the relationship of all this with those articles by Eric Lippert on the design of a Wizards and Warriors?
– Piovezan
Mechanism is all that only concerns the application, which is not part of the solution for the user. It is the GUI (not it applied, but what already exists before its application is the mechanism to build its user interface), it is everything that talks to OS or services as database, is a software configuration, or the authentication system, an automatic workflow or update control, all things underlying the problem. The MVC itself is a mechanism, some Pattern design also. Eventually something connected to the domain but not what is on the front line, the middle and not the end.
– Maniero
Eric has shown how difficult things are and how flawed solutions are. And that to have the ability to reproduce the real world (and this isn’t even a real world, it’s an invention) it needs a lot of complexity, it needs mechanisms that help the domain. It shows that truly object-oriented languages have more ability to deal with it and that what people use is something more or less OO, as I’ve always said, which makes far less sense to use like this, but people insist. And a real OO language is very weak. You have to choose the poison.
– Maniero
Real OO languages like Smalltalk are slow and if the code is not very well written it will have many flaws because it is flexible enough to handle everything that can happen to the object, but there is also no way the compiler will help you much. In the languages that people use to achieve the same effect they have to put a lot of penduricalho and it gets complex. So forgetting the idea of an object as a real-world emulator could help.
– Maniero