Model Driven Design —> (Express Model with) —> { Services, Entities, Value Objects }
Entities —> (Accessed With) —> Repositories
Entities —> (Maintain Integrity With / Act as Root of ) —> Aggregates
Entities —> (Encapsulate with) —> Factories
Chapter 4 - Isolating the Domain
Problem
In an object-oriented program, UI, database and other support code often gets written directly into the business objects. Additionally business logic is embedded in the behavior of UI widgets and database scripts. This happens because it is the easiest way to make things work, in the short run. When the domain-related code is diffused through such a large amount of other code, it becomes extremely difficult to see and to reason about. Superficial changes to the UI can actually change business logic. To change a business rule may require meticulous tracing of UI code, database code, or other program elements. Implementing coherent, model-driven objects becomes impractical. Automated testing is awkward. With all the technologies and logic involved in each activity, a program must be kept very simple or it becomes impossible to understand.
Partition a complex program into layers. Develop a design within each layer that is cohesive and that depends only on the layers below. Follow standard architectural patterns to provide loose coupling to he layers above. Concentrate all the code related to the domain model in one layer and isolate it from the user interface, application, and infrastructure code. The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model. This allows a model to evolve to be rich enough and clear enough to capture essential business knowledge and put it into work.
Entities
Some objects are not defined primarily by their attributes. They represent a thread of identity that runs through time and often across distinct representations. Sometimes such an object must be matched with another object even though attributes differ. An object must be distinguished from other objects even though they might have the same attributes.
An object defined primarily by its identity is called and Entity. An entity is anything that has continuity though a life cycle and distinctions independent of attributes that are important to the application’s user.
Value Objects
Services
A service is an operation offered as an interface that stands alone in the model, without encapsulating state as Entities and Value Objects do. Services are a common pattern in technical framework but they can also apply in the domain layer. A good service should have three characteristics:
The operation relates to a domain concept that is not a natural part of an Entity or Value Object
The interface is defined in terms of other elements of the domain model
The operation is stateless
Services and the Isolated Domain Layer - Services can be at different layer (Application Layer, Infrastructure Layer), but in term of model, we are concerned about Domain Services which is based on the Model
Modules
Everyone uses Modules, but few treat them as a full-fledged part of the model. Code gets broken down into all sorts of categories, from aspects of the technical architecture fo developers’ work assignments. Even developers who refactor a lot tend to content themselves with Modules conceived early in the project. It is a truism that there should be low coupling between Modules and high cohesion with them. Explanation of coupling and cohesion tend to make them sound like technical metrics, and be judged mechanically based on the distribution of associations and interactions. Yet it isn’t just code being divided into Modules, but concepts. There is a limit to how many things a person can think about at once (hence low coupling). Incoherent fragments of ideas are as hard to understand as an undifferentiated soup of ideas (hence high cohesion).
Choose Modules that tell the story of the system and contain a cohesive set of concepts. This often yields low coupling between Modules, but if it doesn’t, look for a way to change the model to disentangle the concepts, or search for an overlooked concept that might be the basis of a Module that would bring the elements together in a meaningful way. Seek low coupling in the sense of concepts that can be understood and reasoned about independently of each other. Refine the model until it partitions according to high level domain concepts and the corresponding code is decoupled as well. Give the Modules names that becomes part of the Ubiquitous language. Modules and their names should reflect insight into the domain.
Modeling Paradigms