Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | |||
| arch:adm [2026/08/29 07:53] – Bulk sync migration user | arch:adm [2026/08/29 07:59] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== POJO, POCO, POPO - WHEN ANEMIC DOMAIN MODEL IS PREFERRABLE? | ||
| + | By **Djambong T. Hank-debaim** (khdzhambongtenke@edu.hse.ru) | ||
| + | |||
| + | ===== Introduction ===== | ||
| + | |||
| + | Software Engineering is the development of software products using best practices, principles, and methods. The focus of this essay is about what is considered best and bad practice. In the next few pages, we will take a quick look into the notion of design patterns, then we will make a critical analysis of the so called Anemic Domain Model (ADM). At that stage, we would assess why it is being labelled as anti-pattern by some. After that, we will consider the good aspects of ADM and why software engineers still use it. As conclusion, I will present my stance on when ADM usage is preferable. | ||
| + | |||
| + | ===== I. Design patterns, DDD, and ADM ===== | ||
| + | |||
| + | **Design patterns** are sets of solutions to common design problems that occur over and over in development. They work as a solution template in which an abstract solution for a common problem is described and the user then applies it, adapting it to their problem. An anti-pattern is just the possible of a pattern. Implementing an anti-pattern within a program is going to affect system performance, | ||
| + | |||
| + | During the years, multiple approaches have been created to help software engineers on developing complex systems. One of those approaches is **Domain-Driven Development (DDD)**. DDD is an approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a domain [1]. In DDD, the development process boils down to creating software abstractions called domain models, which are models of the domain that incorporates both behavior and data [3]. This clearly sets them apart from Entity Objects, which are object representations of only the data stored in a database, while the behavior is in separate classes instead. | ||
| + | |||
| + | In theory, DDD seems logical and shall suit all complex enterprise solutions. However, most developers still do not apply it by its full extent. Rather, they use a “semi-version” of DDD, which lead to the so-called **Anemic Domain Model (ADM)**. An ADM is a design approach using pure-data Entity Classes, with the behavior extracted to another layer, usually called “service layer”. In various programming languages, such classes bear well-known denominations and follow the naming pattern POXO (Plain Old X Object), where X represent the first letter of a specific programming language. For example, in Java they are called POJO, in CLR – POCO, in PHP – POPO, etc. | ||
| + | |||
| + | Why despite its high propagation, | ||
| + | |||
| + | * ADM violates the **encapsulation** and **abstraction** principles of OOP, since the models contain only data and not logic associated with operating those data (except for some getters and setters). | ||
| + | * In the context of model/ | ||
| + | * ADM transforms domain models into mere domain data carriers. | ||
| + | * ADM is a failed attempt to use object-oriented programming, | ||
| + | |||
| + | All those reasons seem good enough for developers to avoid this anti-pattern, | ||
| + | |||
| + | ===== II. ADM is a SOLID design ===== | ||
| + | |||
| + | In ADM, each model only bears the single responsibility of representing an object with its data. This is in accordance with the Single Responsibility principle in SOLID. In the opposite, a model containing both data and operations on those data (Rich Domain Model) has at least 2 responsibilities: | ||
| + | |||
| + | In ADMs, the domain rules, and infrastructural concerns (such as persistence and object construction) are encapsulated in their own services (and presented via abstract interfaces). Consequently, | ||
| + | |||
| + | In the RDM approach, models usually construct and initialize other models’ objects in relation to their own business operations. In this approach, the model also contains the domain logic and check the state of other model’s objects. Finally, by providing persistence (CRUD) operations through a base class, the model entity is also bound to the persistence context. By enumerating these responsibilities, | ||
| + | |||
| + | ===== III. ADM excellently maps to Data Transfer Objects ===== | ||
| + | |||
| + | In computer engineering, | ||
| + | |||
| + | ===== IV. ADM is better for Automated Testing ===== | ||
| + | |||
| + | In ADM, we observe **highly cohesive, loosely coupled** components which communicate via abstract interfaces. Those components are composed via dependency injection allowing for trivial mocking of dependencies. Therefore, scenario construction is made easier during automated test. In RDM, this process is more complicated to construct since tight coupling proliferates, | ||
| + | |||
| + | [[arch: | ||
| + | |||
| + | Suppose we ought to write unit tests on the // | ||
| + | |||
| + | * construct a // | ||
| + | * configure that customer to have enough funds, | ||
| + | * configure the customer region to be outside the allowed shipping regions for that item, | ||
| + | * at the end, we need to assert that // | ||
| + | |||
| + | However, the // | ||
| + | |||
| + | On the other hand, ADM requires us to: | ||
| + | |||
| + | * express the // | ||
| + | * provide a stubbed, mock implementation of // | ||
| + | |||
| + | ===== V. Anemic Domain represents developers’ view of OOP ===== | ||
| + | |||
| + | Within the software engineering community, there is a long discussion going on about what logic can be implemented within a domain model to interact with itself. The problem is that if implementing RDM, we quickly enter a situation where we must write a logic like this: // | ||
| + | |||
| + | This is exactly how most software engineers understand OOP. If it is needed to perform some operations on a set of objects or persist those objects, it seems more logical to have a separate service performing those operations, rather than having the objects performing those operations on themselves. | ||
| + | |||
| + | ===== VI. Procedural programming is easier to catch ===== | ||
| + | |||
| + | One of the arguments mentioned by the detractors of ADM is that //“ADM is a failed attempt to use object-oriented programming, | ||
| + | |||
| + | ===== Conclusion ===== | ||
| + | |||
| + | In this essay, we took a quick look into the notion of design patterns, then we made a critical analysis of the so called Anemic Domain Model (ADM). We assessed why it is being labelled as an “anti-pattern” by some. After that, we considered the good aspects of ADM and why people still use it. Despite its multiple cons, I personally consider ADM to be a great approach in software design. It helps build applications with domain models that follow the SOLID principles. Three scenarios when ADM is preferable: | ||
| + | |||
| + | * When working in presence of a ORM library to operate data with the persistence layer. | ||
| + | * When the system’s business logic implies strong coupling between models. | ||
| + | * When testability is important, but we want to spend minimal time modifying / refactoring tests in each new model modification. | ||
| + | |||
| + | ===== References ===== | ||
| + | |||
| + | - [[https:// | ||
| + | - [[https:// | ||
| + | - [[https:// | ||
| + | - [[https:// | ||
| + | - [[https:// | ||