Por qué no hacemos todo en spreadsheets?

Much of the domain logic we write exists to enforce these constraints in order to maintain the invariants of the system. The invariants are the things that have to be true whenever we finish an operation.

Constraint: Regla que restringe los posibles estados en los que puede estar nuestro modelo Invariant: Condición que siempre será verdadera - Un hotel no puede tener 2 reservas para la misma noche

Invariants de nuestro dominio

  1. An order line can be allocated to only one batch at a time.
  2. We can’t allocate to a batch if the available quantity is less than the quantity of the order line.

Aggregates

An aggregate is just a domain object that contains other domain objects and lets us treat the whole collection as a single unit. Pararelismo con Python:

  • Clases públicas - aggregate
  • Clases privadas - resto de las entidades Ejemplo: Carrito de compras
  • contiene N elementos a los que podemos tratar como una sola unidad

One aggregate = One Repository

TIP

The rule that repositories should only return aggregates is the main place where we enforce the convention that aggregates are the only way into our domain model. Be wary of breaking it!

# uow.py
class AbstractUnitOfWork(abc.ABC):
    products: repository.AbstractProductRepository
 
# repository.py
class AbstractProductRepository(abc.ABC):
 
    @abc.abstractmethod
    def add(self, product):
        ...
 
    @abc.abstractmethod
    def get(self, sku) -> model.Product:
        ...

Resumen

The idea of an aggregate

Explicitly model an object as being the main entrypoint to some subset of our model, and as being in charge of enforcing the invariants and business rules that apply across all of those objects.

Aggregates are your entrypoints into the domain model

By restricting the number of ways that things can be changed, we make the system easier to reason about.

Aggregates are in charge of a consistency boundary

An aggregate’s job is to be able to manage our business rules about Invariants as they apply to a group of related objects. It’s the aggregate’s job to check that the objects within its remit are consistent with each other and with our rules, and to reject changes that would break the rules.

Aggregates and concurrency issues go together

When thinking about implementing these consistency checks, we end up thinking about transactions and locks. Choosing the right aggregate is about performance as well as conceptual organization of your domain.

Chapter 08 - Events and the Message Bus