3. ...and so it begins...
- Libro di Evans del 2004
- Descrive (prescrive?) un insieme
di patterns e metodologie di
analisi e implementazione
4. “Talk is cheap, show me the code”
“DDD...show me the code”
@emadb, 2011
5. DDD Purpose
● To build a domain (business) model, NOT a data model (anaemic domain)
● To express domain concepts in the code
● To make the implicit explicit (including, but not limited to, errors)
7. Bounded context
● It’s impossible to build and
maintain a model for a large,
complex organization: divide et
impera
● The preferred way of
communication between
bounded contexts is using Domain
Events via pub/sub
8. Ubiquitous language
● Rigourous language, no ambiguity
● It’s the language we use in the code, to name our domain concepts
● Usually valid only inside a bounded context
9. Core domain distillation
● DDD is expensive both in analysis and implementation, so it’s important
to know where to use it
● Every large domain has various supporting subdomains for every core
domain
● Usually found following the money :-)
11. Entities and Aggregates
● An entity is just a PO(C|J)O object that
expresses a domain concept and
enforces the domain invariant(s)
● Persistence ignorance
● Holds the business logic of the domain
and its state
● Has an identity throughout the
bounded context (Identity equality)
● An aggregate is a transaction
boundary consisting in several entities
held together by an aggregate root
12. Value Objects
● Plain simple records
● Immutable
● Structural equality (no identity)
13. Entities vs Value Objects
● Should this be and Entity or a Value Object? The answer can be subtle or
obvious, and depends mostly on the context
● Usually in a 70/30 ratio
14. Domain Services
● “The operation relates to a domain concept that is not a natural part of an
Entity or Value Object”
● First class citizens of the domain
● Stateless
15. Domain Events
● “Nel dominio è successo qualcosa di interessante per un domain expert”
● Can (asynchronously) cross the boundaries of an aggregate
● Compensating events
16. Repositories
● A repository is a class whose sole purpose is to collaborate with an entity for
data persistence
● SRP is enforced
● Emphasys on the data access pattern, which is made explicit
17. Factories/Validators
● Responsibles for creating the entities
● Anti corruption layer
● The domain has to be always valid, creating entities in invalid state must
be impossible
● Usually there is a strong coupling between factories and the entities they
create, but that’s ok.
22. DDD + CQ(R)S
● Only way I’ve found to write a reliable, rock solid DOMAIN model
● Domain Entities
○ Enforces invariants
○ Express business model, relationships
○ Have only public methods
○ They’re the write part of the model
● Views
○ Used for queries:
○ Very dumb, no business logic (only a little, if any, of presentation logic)
○ They’re read-only for the domain (i.e.: they come out, never go in)
○ Tailored to the specific user view (there are A LOT of views, but that’s ok)
23. How I do it (with a single RDBMS)
public interface IDbDto<DTO> {
TDto ToDto();
void Load(TDto dto);
}
- Dtos are the ONLY data saved to and loaded from the database
- The interface is hidden until we do a cast (which can only be done in the repository)
- The Dtos are used to hydrate (fill the data in) the views and the entities alike
Every entity explicitly implements the interface IDbDto
24. ● Very dumb class
● No constructor
● Everything is public
● Usually denormalized
● Read-only for the domain
● Constructor sets the identity
● Class enforces domain invariants
● No public properties (even read-only)
● Public methods only
● State is completely private
public class Cart : IDbDto<CartDto>
{
public Guid Id {get; }
public Cart (Customer
customer);
public Unit AddItem(Item item);
public Unit CheckOut();
}
public class CartView
{
public ItemView[] Items {get; set}
public string CustomerName {get;
set;}
public string CustomerAddress {get;
set;}
public double Amount {get; set;}
}
public class CartDto
{
public Guid Id {get; set}
public Guid CustomerId {get;
set}
public ItemDto[] Items;
}
● Another dumb class
● Usually Normalized
● No constructor, public
● This is where an ORM
may be handy
25. Functional DDD
● Really? It’s intrinsically anaemic (Record + Services)
● CQRS (State as application of a series of events) fits better