Most business domains have very interconnected Entities, sometimes up to the point where there is always a path going from any Entity to any other. We can try to minimize the number of associations in our design, and this is a good practice but it can lead to a translation loss between business and software. In a typical object model, it is difficult to clearly see the boundaries of a change. This is particularly acute in systems with concurrent access such as Web applications.
An Anemic Domain Model is something that can be found a lot of projects and, astonishingly, is often viewed as a good practice. But as you may already have deduced from its name, it doesn’t sound like something desirable and certainly not in DDD-oriented software.
Sometimes behavior doesn’t fit into Entities or Value Objects. Pure operations may exist in the domain and should therefore be modeled as such. Domain-Driven-Design propose the Service pattern to model these operations.
Modeling business concepts with objects may seem very intuitive at first sight but there are a lot of difficulties awaiting us in the details. To clarify the meaning of model elements and propose a set of design practices, Domain-Driven Design defines three patterns that express the model: Entities, Value Objects and Services. This chapter will focus on Entities and Value Objects, leaving Services for their own chapter.
An aggregate is a cluster of cohesive entities and value objects that is treated as a single unit.
Aggregates have clear boundaries and are loosely coupled to each other.
Domain-Driven Design itself can be successfully applied in variety of software architectural styles. Some are very broad and tend to define every aspect of the system, others are more focused and try to address a specific demand. The business framework itself can adapt to several architectural styles. This documentation will focus on the traditional layered architecture from the Eric Evans DDD book, improved by the usage of the Dependency Inversion Principle.
An assembler is an interface object responsible for mapping one or more aggregate(s) to a Data Transfer Object (DTO) and back.
SeedStack business framework is a simple and coherent set of building blocks that enable you to code high quality business logic efficiently.
This is the reference manual for all topics of the Business framework. It is best to have a good understanding of the essential notions before going further into this reference manual. Entities An entity is used to represent a domain concept distinguished by an identity. This identity must remain the same through the whole entity lifecycle. Characteristics Declaration Example Value Objects A value object is used to describe or compute some characteristic of a domain concept.
A domain event is used to represent something that happened in the domain.
It happened in the past and is of interest to the business.
A reusable JAR designed to contain one or more business domain(s) based on the business framework.
Domain-Driven Design (DDD) is an approach to the development of software that: Focuses on the core domain. Explores models in a creative collaboration between business experts and the software team. Defines an ubiquitous language within an explicitly bounded context. Domain-Driven Design has two sides, both equally important: Strategic design, which address high-level considerations of domain knowledge and its modeling. Tactical design, which propose practical patterns to design the required software.
An entity is used to represent a domain concept distinguished by an identity.
This identity must remain the same through the whole entity lifecycle.
A factory is responsible for creating a whole, internally consistent aggregate when it is too complicated to do it in a constructor.
A finder encapsulates interface-specific data queries that have no business meaning.
It only has read-only operations.
We recommend a well-defined package layout for organizing your business code according to the software architecture described above. The domain The root package for the domain layer is: [base.package].domain The domain can be composed of several sub-domains that can be specified as sub-packages: [base.package].domain.subdomain1 [base.package].domain.subdomain2 ... The domain package (or each sub-domain package if relevant) contains: A model package containing aggregates, each in its own package. An aggregate package contains The aggregate root along with other related entities and value objects, The factory interface if any, The repository interface if any, The aggregate policies if any.
A policy is used to encapsulate a varying business rule or process in a separate object.
Multiple versions of the policy object represent different ways the process can be done.
With the business framework, much like the rest of SeedStack, you declare injection points with an interface type not an implementation one. The framework discovers any implementation of a specific interface and will inject it through its interface. For a specific interface, the business framework supports multiple implementations. This is particularly useful when you have multiple algorithms of implementation technologies for an interface. If multiple implementations of a specific interface are found, you must use a qualifier on each one to differentiate them.
To go beyond what is described in this documentation, we recommend a few books which will help you to better understand DDD, independently of the business framework. Domain-Driven Design community This is a major online resource about Domain-Driven Design with a lot of contents to discover and learn about it. Online community Eric Evans: Domain-Driven Design Reference This book by Eric Evans is a summary of patterns and definitions of Domain-Driven Design.
A repository is responsible for consistently storing and retrieving a whole aggregate.
It has a simple collection-like global interface and optionally domain-specific methods.
A service is a stateless object that implements domain, applicative or infrastructure logic.
Now it is time to write the domain of the application. To do so, we will use the business framework which is implementing Domain-Driven Design principles and patterns.