This post outlines the key points of Domain-Driven Design by Eric Evans.
1. Continuous Learning & Knowledge Crunching
Regulary converse with domain experts to develop a language, based on the model. Seek to continously improve the model.
2. Ubiquitous Language
Developers should pursue a ubiquitous language; one that helps developers and domain experts talk about the same model. A change in the language represents a change in the model.
3. Unifying your model with your code
Any representation of the model (documentation, UML or diagrams) should tie in directly to your code. You should see the same model concepts in your code that you see on a diagram.
4. Isolating to domain
Separate the domain logic from non-business specific code (UI, Database, Currency ect).
5. Coding the model
Associations between objects is a key component of good domain design:
5.1. Impose a direction
5.2. Add a qualifier (eg. rather than saying a country has had many presidents, we can say that a country has one present at any one time. This reduces the association to a one-to-one)
5.3. Eliminate non-essential associations
Entities are unique objects that are defined by more than just their attributes (a person or a car).
When modeling entity objects, strip the objects down to its defining characteristics. Any attributes that are not essential should be moved into other objects associated with the core entity.
Value objects have no identity and are interchangeable with other value objects. Value objects are transient, they can be destroyed or created without thought. Value objects are immutable.
Value objects should be used to simplify entities. For example, an address can be removed from a Customer class, into an address value object.
Services Some concepts do not belong as objects, they may be more suited to services. A service should be stateless.
Modules Modules should have low coupling in the sense that they can be understood independently. Give modules a name that becomes part of the ubiquitous language.
6. Domain Object Life Cycle
An Aggregate is a cluster of associated objects that we treat as a unit (eg, a car). Aggregates have one root which is allowed to communicate with external objects.
A Factory should be used when creation of an object or aggregate becomes complex. Assembly corresponds to a milestone in the domain (eg. open a bank account). When designing the interface:
6.1. You must pass in everything required to create a complete product
6.2. A factory will be coupled to its arguments. Picking lots of parts out of objects to use as arguments can create a rats nest.
A Repository represents all objects of a certain type; it acts like a collection except it allows for more elaborate queriying capabilities.
7. Constantly Re-factor
Constantly re-factor towards a deeper insight, small changes can add up and lead to large changes in the model.
8. Making implicit concepts implicit
When domain experts use words that are not in the design, that is a lead. Scrutinize awkwardness in your domain model and study contraditions. Use predicate value objects for specifications.