Domain-driven
design:
Repositories
Eleonora Ciceri - 8 February 2022
1
What is a repository?
A repository is used to manage aggregate persistence and retrieval, while
ensuring that there is a separation between the domain model and the data
model
2
domain model data model
repository
it restricts access to domain
objects by only allowing the
retrieval and persistence of
aggregate roots (so that
invariants are guaranteed)
it offers a domain-specific
interface while hiding the
underlying technology used to
persist and retrieve
aggregates
it defines a boundary between
the domain model and the
data model (that is, it acts as
an ACL)
How does a repository look like?
The interface is kept within the domain model namespace, because it is part
of the domain model
(side note: you can name it in a more domain-related way, e.g., CustomerBase, so as to
avoid pollution of the domain with terms such as Repository)
The implementation is part of the infrastructure (adapters, in case of
hexagonal architecture) and is backed by a persistence technology
3
interface CustomerRepository {
Customer findById(CustomerId id);
void save(Customer customer);
void remove(Customer customer);
}
Domain model vs. Data model (1)
4
Domain model
Customer
AddressBook
A domain model is
- an abstraction of the problem
domain, rich in behavior and
language
- made of aggregates, entities, value
objects
Data model
Customer has AddressBook
name surname
Address
FullName
made
of
Address
street
city
A data model is
- a storage structure to contain the
state of the domain model at a
given time
- made of tables and columns
Domain model vs. Data model (2)
5
Domain model Data model
A domain model speaks the ubiquitous
language
A data model speaks the language of
persistence
patient
discharge
bed
ward
therapy
SQL
query
table
attribute
statement
Please do not use a single model (1)
We do not want to write a single model and use it as both domain model and
data model
6
This class
changes for
reasons related
to the domain
This class also
changes for
reasons related
to the
persistence
Please do not use a single model (2)
We do not want to write a single model and use it as both domain model and data
model
It is unclear what in that class has been written to support the domain and what has
been written because it is necessary for the persistence to work
7
Domain model
Data model
getId()
Decoupling domain and data models
Instead, you want to separate the two models so that they are free to
change independently
8
Domain model
Data model
The repository is an integration point
The repository (or better, its implementation) knows both languages and is
thus the integration point between the two models
9
Domain model
Data model
repository
Accessing a repository: only by aggregate!
You should NEVER allow access to an object internal to an aggregate: if you want to access it, do it
by traversing from the aggregate root!!
Free database queries can actually breach the encapsulation of domain objects and aggregates
10
Customer
AddressBook
Address
FullName
If you want to access an address query
by Customer and then traverse through
AddressBook …
Customer
AddressBook
Address
FullName
…but never, never allow a query from
outside the aggregate!
Introducing our friends, the snapshots
We can use the memento pattern, in which
- an aggregate produces a snapshot of itself, i.e., a version of itself that can
be persisted
- the aggregate knows how to hydrate itself from the same snapshot
11
.fill(CustomerSnapshot)
.fromSnapshot(CustomerSnapshot)
FullName name;
AddressBook book;
Customer
String name;
String surname;
AddressBookSnapshot book;
CustomerSnapshot
Snapshots vs data models
It is important to understand that a snapshot is NOT the data model! It is just the state of an
aggregate
The repository has to map the snapshot to the data model
12
The snapshot
It captures the state of the
aggregate in a certain
moment
The aggregate
It is a living, breathing part
of the domain model, with
its own state and behavior
Name Snapshot
San Francisco
Table: City
References
13
References
[1] Vlad Khononov, Learning Domain-Driven Design - Aligning Software
Architecture and Business Strategy, O’Reilly, 2022
[2] Scott Millett, Patterns, Principles and Practices of Domain Driven Design,
Wrox, 2015
[3] Vernon & Evans, Implementing Domain-Driven Design, Addison-Wesley
Professional, 2013
[4] https://kalele.io/the-ideal-domain-driven-design-aggregate-store/
14

DDD - 5 - Domain Driven Design_ Repositories.pdf

  • 1.
  • 2.
    What is arepository? A repository is used to manage aggregate persistence and retrieval, while ensuring that there is a separation between the domain model and the data model 2 domain model data model repository it restricts access to domain objects by only allowing the retrieval and persistence of aggregate roots (so that invariants are guaranteed) it offers a domain-specific interface while hiding the underlying technology used to persist and retrieve aggregates it defines a boundary between the domain model and the data model (that is, it acts as an ACL)
  • 3.
    How does arepository look like? The interface is kept within the domain model namespace, because it is part of the domain model (side note: you can name it in a more domain-related way, e.g., CustomerBase, so as to avoid pollution of the domain with terms such as Repository) The implementation is part of the infrastructure (adapters, in case of hexagonal architecture) and is backed by a persistence technology 3 interface CustomerRepository { Customer findById(CustomerId id); void save(Customer customer); void remove(Customer customer); }
  • 4.
    Domain model vs.Data model (1) 4 Domain model Customer AddressBook A domain model is - an abstraction of the problem domain, rich in behavior and language - made of aggregates, entities, value objects Data model Customer has AddressBook name surname Address FullName made of Address street city A data model is - a storage structure to contain the state of the domain model at a given time - made of tables and columns
  • 5.
    Domain model vs.Data model (2) 5 Domain model Data model A domain model speaks the ubiquitous language A data model speaks the language of persistence patient discharge bed ward therapy SQL query table attribute statement
  • 6.
    Please do notuse a single model (1) We do not want to write a single model and use it as both domain model and data model 6 This class changes for reasons related to the domain This class also changes for reasons related to the persistence
  • 7.
    Please do notuse a single model (2) We do not want to write a single model and use it as both domain model and data model It is unclear what in that class has been written to support the domain and what has been written because it is necessary for the persistence to work 7 Domain model Data model getId()
  • 8.
    Decoupling domain anddata models Instead, you want to separate the two models so that they are free to change independently 8 Domain model Data model
  • 9.
    The repository isan integration point The repository (or better, its implementation) knows both languages and is thus the integration point between the two models 9 Domain model Data model repository
  • 10.
    Accessing a repository:only by aggregate! You should NEVER allow access to an object internal to an aggregate: if you want to access it, do it by traversing from the aggregate root!! Free database queries can actually breach the encapsulation of domain objects and aggregates 10 Customer AddressBook Address FullName If you want to access an address query by Customer and then traverse through AddressBook … Customer AddressBook Address FullName …but never, never allow a query from outside the aggregate!
  • 11.
    Introducing our friends,the snapshots We can use the memento pattern, in which - an aggregate produces a snapshot of itself, i.e., a version of itself that can be persisted - the aggregate knows how to hydrate itself from the same snapshot 11 .fill(CustomerSnapshot) .fromSnapshot(CustomerSnapshot) FullName name; AddressBook book; Customer String name; String surname; AddressBookSnapshot book; CustomerSnapshot
  • 12.
    Snapshots vs datamodels It is important to understand that a snapshot is NOT the data model! It is just the state of an aggregate The repository has to map the snapshot to the data model 12 The snapshot It captures the state of the aggregate in a certain moment The aggregate It is a living, breathing part of the domain model, with its own state and behavior Name Snapshot San Francisco Table: City
  • 13.
  • 14.
    References [1] Vlad Khononov,Learning Domain-Driven Design - Aligning Software Architecture and Business Strategy, O’Reilly, 2022 [2] Scott Millett, Patterns, Principles and Practices of Domain Driven Design, Wrox, 2015 [3] Vernon & Evans, Implementing Domain-Driven Design, Addison-Wesley Professional, 2013 [4] https://kalele.io/the-ideal-domain-driven-design-aggregate-store/ 14