External classes can only have associations with the Aggregate Root
External classes can use the other aggregated classes (temporary links)
For instance, as the return type of an operation
Tactical Patterns
Gerson Sunyé gerson.sunye@univ-nantes.fr
Entities instances are objects whose state changes over time,
but whose identity remains the same
Entities are classes that represent domain concepts
They should have business logic
Their instances have an unique identifier,
which remains the same throughout its lifecycle.
They are mutable
Identities should be different from Object Ids (OID)
Entities are persistence agnostic
Value Objects are containers of attributes
They are immutable and have no identity
They may be shared between different entities
Attributes must be read only
Operations must not have side-effect
Value Objects have their own behavior and significance to the model
Sometimes, Value Objects are Entities in different contexts
| Value Object | Entity | |
|---|---|---|
Identity | No (but may be an identifier) | Unique |
Mutability | Should be immutable | Usually mutable |
Equality | Comparison by value | Comparison by Identity |
Scale | Typically small | Any size |
Operation behavior | No side-effects | Can have side-effects |
Serializable | Should be serializable | No need |
Defaults | Often have a natural default | No natural default |
User Interface | Dedicated widget | Tailored (hand coded) |
Business rules | Limited/No | Encapsulates behavior and rules |
Cluster of entities and value objects
An aggregate defines the boundaries,
its components are only accessible through an Aggregate Root
The objects inside an aggregate are persisted together (within the same transaction)
The aggregate ensures that consistency rules are applied synchronously
An Entity that has the responsibility of ensuring the aggregate invariants
The only entry point of the aggregation
External classes can only have associations with the Aggregate Root
External classes can use the other aggregated classes (temporary links)
For instance, as the return type of an operation
Since aggregated objects cannot be modified from outside, invariants are simpler to implement
for instance, bidirectional associations
Aggregates may be nested
A cluster of objects treated as a single unit
Only accessed through its Root Entity
Often associated to a State Machine
The atomic unit for any transactional behavior.
Responsible for maintaining business invariants.
Creating aggregates may be complex: several objects must be created and connected during the creation
In this case, developers use Factory Methods
Factories may also be used to create Value Objects
See the Flyweight design pattern
Minimizes object creation
In most cases, the root is a good choice
The root controls all aggregated objects
Otherwise, use a separate factory
When the root is not responsible for some aggregated objects
In some cases, a factory method is not needed:
The construction is simples
All required attributes are available
The construction is for Value Objects
Abstraction that encapsulates a storage mechanism
Provides the illusion of an in-memory collection of Aggregate Root objects
A way to retrieve and store domain objects
Provide methods that select objects based on criteria meaningful to domain experts
One Repository per Aggregate (very explicit)
Generic Repository
One Repository per aggregate built upon Generic Repository Strategy
Generic Repository with Specifications
Provides explicit methods
| Advantages | Drawbacks |
|---|---|
|
|
Provides generic, open query methods
| Advantages | Drawbacks |
|---|---|
|
|
Mixes the best of both worlds
| Advantages | Drawbacks |
|---|---|
|
|
Generic functionality with explicit query functionality
| Advantages | Drawbacks |
|---|---|
|
|
Simple interface for defining criteria
Similar to the Query Object pattern
Easy to test
Easy to chain together for more complex queries: And, Or, Not
aka packages
Contains cohesive set of concepts
Break up your domain to reduce complexity
Becomes part of the ubiquitous language
Helps with decoupling
Aids in extensibility
When you place some classes together in a Module, you are telling the next developer who looks at your design to think about them together.
The first client for the domain model
Assembles stateless operations that do not conceptually belong to Entities nor to Value Objects
Services are a natural part of a model
Domain services should be distinguished from other services (application, infrastructural)
Use domain services sparingly
Focus on domain logic, not application or infrastructure concerns
Name services using verbs or verb phrases to reflect their behavior
Something happened that domain experts care about
Event captures a change to the model so different model components can observe these changes and react accordingly
A record of a business-significant occurrence within a Bounded Context
New Borrowing
Buy Book
Entities are responsible for tracking their states
Often, changes are not explicit
Changes can be tracked, but are hard to explain
In a distributed system
Changes must be propagated to ensure consistency
Events model actions as a series of discrete events
Represented as domain objects
Full-fledged part of the domain model
Immutable
Contains a domain description and entity identifiers
Sometimes contain timestamps and sender id
Sometimes contains an id