What is a "Domain Model"?

    Hi, Habr.

    Today I went to the #school channel in the Russian-language GoCommunity in Slack and found one interesting dialogue there . This dialogue led me to some thoughts about how my colleagues interpret the concept of “domain model” .

    As it turned out, there are quite a lot of incorrect or not quite accurate, and sometimes completely inaccurate interpretations of this term, which essentially distorts it. Around this dialogue, the idea of ​​this article was born. Details under the cut.

    Question about architecture.

    So, the developer asked the following question in the community:
    Tell me how to do the architecture correctly, let's say I made a tablet in the database, asked the reforms to generate a model for me, can I use this model as a domain model in my application, or is it better to create my own domain model and make an adapter that will give me exactly my domain model creating it from a reform model? ”

    To which another programmer gave the following answer:
    The simplest is architecture with an anemic model. this is when the DB model = domain model = API response model. rich domain model is a rare beast and usually degenerates into anemic. By anemic is meant a DTO structure. the usual set of attributes (fields) without methods. Logic degenerates into a set of functions that operate on such dto. Fowler at times considers such an architecture to be antipattern. But then a good microservice solution, etc.

    After reading this, I suddenly realized why there is so much controversy surrounding the organization of the business logic layer, and why many people fail to put into practice such approaches as Clean Architecture , etc. What does “architecture with an anemic model” mean ?

    If you try to find such a concept on the network, you most likely will not find it, because there is no such architecture. There is the concept of “AnemicDomainModel” , and if we turn to the same Fowler, it turns out that this is just a procedural approach to creating an application architecture (hello Fortran, ALGOL, COBOL, BASIC, Pascal and C). This, in essence, is what the author of the answer calls “architecture with an anemic model” .

    The domain model.

    Next, the next question arises: is the “anemic model” essentially a model? I think not, and that's why.

    The truth is that the domain model is not a data model, unlike the “DB model” or “API response model” . The domain model has a very specific definition . Moreover, it is wrong to interfere with the database model, which is essentially a data model .

    When it comes to the domain model, this is precisely the conceptual model. And this is the totality of the concepts of the subject area and the relations between them (i.e., the totality of behavior and data). In general, the main feature that distinguishes one model of a subject area from another is precisely a set of business rules.

    Yes, the conceptual model can work with data that is presented in different forms (data from the database or API responses), but the essence of this will not change, the behavior is paramount. We pass the input to the model to get a specific output. This result is achieved by implementing business logic within the model (in other words, applying business rules). I find here an analogy with mathematical models and modeling of technological processes (hello student years).

    What is fraught with the substitution of concepts?

    When you call data structures a “domain model” , you are free or not to replace concepts. This leads to the fact that often business logic is spread throughout the application. In fact, the model of the subject area in this case is the very smeared set of functions that operates with data structures.

    In the case of developing medium and large applications, a misunderstanding or mixing of these concepts, as a rule, leads to a number of problems and questions already at the start of system development, not to mention long-term support. Among them, for example, there are such common questions as:

    • "- Where to validate the data?"
    • "- How to avoid cyclic dependencies?"
    • "- Is“ this ”business logic in general?"
    • "- And where do we keep the business logic?"
    • etc.

    Moreover, if you have a simple CRUD, i.e. essentially an interface to the database, there will most likely be no problems. If you are writing an infrastructure-level library (for example, for working with a network or with the same database), there should also be no problems. That's because there is an RFC and all the “business rules” have long been clear, and the logic has long been clear. You can write a simple procedural program, and everything will be fine anyway.

    If we return to the fact that the dialogue about domain models arose in the Go community, I would say so. Due to the fact that Go is a multi-paradigm language and supports a number of the most successful OOP concepts (Composition, Interfaces), do not ignore them when modeling a domain and write code exclusively in a procedural style, as if you are working with BASIC or C.

    Correctly interpreting the concept of “domain model”, it becomes quite obvious why it is often customary to separate business logic into a separate layer. It also becomes clear how you can select this same layer and implement Clean Architecture or any other variation of it. By isolating a separate layer, we essentially create a library that implements the conceptual model in the form of program code. As a result, business logic becomes encapsulated within the framework of this library, and not spread out throughout the application (as with a pure procedural approach).

    Of course, understanding these concepts will not save you from design mistakes, will not make you an ideal developer or systems architect, and will not teach you to do everything right the first time. Here, not only theory is important, but also practice. Nevertheless, as soon as you correctly understand the concepts and interpret the definitions, many things will become much more obvious and simpler for you.

    To summarize.

    • It is not correct to call “data” a domain model.
    • A domain model is a conceptual model that includes both behavior and data. It can be encapsulated in a separate layer, or it can be spread throughout the application.
    • “Architecture with an anemic model” is nothing more than a procedural approach to creating an application architecture in which the domain model is spread throughout the application

    Pay attention to definitions, study them deeper than just reading diagonally. Very often we are lazy and grab information in pieces, after which distortion certainly occurs. Do not forget to come back and remember things that seem obvious to you for a long time, and always refer to the sources and call a spade a spade.

    Good to all! Thanks for attention.

    PS. I will be glad to listen to constructive criticism, as well as your vision of what a “domain model” is. References to the source are welcome.

    UPD: The article is not an attempt to freely interpret the concept of "domain model" and to put into this concept one meaning that I know of. I want to convey this:The meaning in this concept has long been invested, and it is described in detail in books and articles on ComputerScience. The article is an attempt to convey to colleagues on the importance of the correct perception of these very concepts without distorting their meaning (This is important because in practice it will allow you to write more meaningful code).

    UPD2: I'm not an enterprise theoretician architect. I’m the same practicing developer as you are. I write code every day and talk about these things in order to make my code better, and customers happier. If, in your opinion, I have distorted the original meaning, share links to the source and indicate where I put it incorrectly, so that I can fix it.

    UPD3:Because many interpret the term “subject area” in different ways, I give some examples of subject areas so that there is no confusion and substitution of concepts. The subject area always depends on what problem you solve using application development:

    • Booking tickets (if you are a developer of reservation systems)
    • Banking (if you are a developer of banking applications)
    • Operating Systems (If you are a developer OS developer)
    • Cloud infrastructure management (if you are a k8s developer)
    • Virtualization (If you are a Docker developer)
    • Performance Monitoring (If you are a Prometheus / Grafana developer)

    Also popular now: