My notes on “Refactoring from Anemic Domain Model” by Vladimir Khorikov

This post is just to share my notes on the course “Refactoring from Anemic Domain Model Towards a Rich One” by Vladimir Khorikov.
https://app.pluralsight.com/library/courses/refactoring-anemic-domain-model

Module #2 – Introduction
– Problems with an anemic domain model: discoverability of operations, potential duplication, lack of encapsulation.
– Encapsulation is about protecting data integrity (no operation should be able to violate the invariants of a class, an aggregate). Protecting you from doing something incorrectly.
– Encapsulation is so important to maintain because without it we can’t cope with the increasing complexity of the code base (slows down development, increases the number of bugs).
– Anemic domain model always means the lack of encapsulation.
– If classes with data do not impose any restriction, the services with operations are the ones that should know how to keep the integrity and always remember to do it (potential duplication).
– An anemic model can be adequate for small projects that are not going to be developed for a long time. Also, different bounded contexts can have different needs.
– Anemic Domain Model and Functional Programming?. FP encourages immutable data structures and operations separated from them. Vladimir mentions that with FP immutability there is no need to worry about corruption of internal state, hence FP does not suffer from the lack of encapsulation. It suffers from discoverability of operations.
– In my experience I believe that immutability alone does not prevent us from breaking the invariants, an operation can’t change an object but can return a new copy changing one property in a way that breaks integrity. To solve that issue I would say that we should always use a constructor (which enforces invariants) to instantiate objects and not use the cloning mechanism provided by the language to bypass invariants validation.
Continue reading “My notes on “Refactoring from Anemic Domain Model” by Vladimir Khorikov”

My notes on the video course “CQRS in Practice” by Vladimir Khorikov.

I completed the course and I sincerely recommend it to anybody that wants to learn more about the Command Query Responsibility Segregation (CQRS) pattern and Domain-Driven Design (DDD) in general.

The course does not cover Event Sourcing (ES), what I like because allows learning CQRS in-depth avoiding getting confused with the most advanced CQRS+ES or getting advice that only applies when ES is been used.
That said, I would love if Vladimir can expand his DDD course series with a Event Sourcing course ;-).

Vladimir introduces all the concepts in a good progression, by layers (API, Domain, Database) and complexity, reminding us that there is no need to apply a full CQRS pattern to start getting benefits from it.

My notes:

Module #1 – Introduction
– With CQRS instead of having one unified model we have two: one for reads and another for writes.

Module #3 – Refactoring Towards a Task-based Interface
– Task-based Interface vs CRUD-based Interface.
– I found really good and realistic the example Vladimir uses, a legacy system exposing a single update endpoint is used by the UI for diverse uses cases (edit personal info, enrolling/disenrolling, transferring student), but nothing is explicit in the API side. What is there is a huge update method doing multiple things. The video shows how to split and refactor it away from a CRUD API to a task-based interface.
– Task-based interface involves not only the API also the UI.

Module #4 – Segregating Commands and Queries
– The terms Command and Query are overloaded, they mean command or query method in the context of CQS but just a data class in the context of CQRS.
– The objects representing our Commands and Queries belong to the Domain Model, as the Domain Events do (all 3 are “messages”). What does not belong to the domain layer are the Handlers that are part of the Application Services layer.
– Vladimir depicts an Onion Architecture with 3 layers: Core domain (Entities, Aggregates, Value Objects, Domain Events, Commands, Queries, Pure Domain Services), Non-core domain (Repositories, Impure Domain Services), Non-domain (Application Services, Command Handlers, UI).
– Commands follow the push model whereas Events follow the pull model.
– Commands and Data Transfer Objects (DTOs) are different things, they tackle different problems. Think in Commands as serializable method calls (calls in the domain model) whereas DTOs are data contracts between the API and its clients. This separation layer allows us to refactor or evolve the domain model without introducing breaking changes in the API (backward compatibility). We are used to doing this in our mapping between Entities and DTOs.
– Vladimir makes a really good point explaining that the reason why people often don’t see commands as part of the domain model is that in the controllers they skip the mapping stage and directly use commands for the request/response body. Don’t do that.
Continue reading “My notes on the video course “CQRS in Practice” by Vladimir Khorikov.”

DDD – Aggregate Roots and Domain Events publication

Implementing DDD in a traditional object-oriented style *, when an action over an Aggregate succeeds the state of the aggregate changes and one or multiple domain events are published.
A Domain Event represents something that has happened in the domain. In the other hand if the action cannot be fulfilled a Domain Error is thrown as an exception by the aggregate.

Publishing Domain Events from an Aggregate
The question that arises here is Should the aggregates publish events directly?. We can find a multitude of articles and examples where the Aggregate implementation does exactly that. The very same Vaughn Vernon’s IDDD book shows this approach (page 300):

public class BacklogItem extends ConcurrencySafeEntity {
  ...
  public void commitTo(Sprint aSprint) {
  ...
    DomainEventPublisher
      .instance()
      .publish(new BacklogItemCommitted(
         this.tenantId(),
         this.backlogItemId(),
         this.sprintId()));
    }
  ...
}

the BacklogItem Aggregate creates and dispatches an event directly using a DomainEventPublisher instance before the database transaction is commited.

This approach can become quite complex to implement right, because of the transactional concerns. Think about it, if the aggregate publishes events directly, what happens if later on the persistence operation fails?
Unit testing of aggregates gets also complicated, the aggregate is coupled to a DomainEventPublisher that it instantiates directly. At the same time, we know that we should avoid dependency injection into an Aggregate.

An alternative approach is to use a Two-steps event publication

  • 1st) Aggregate root creates and registers domain events for publication.
  • 2nd) When the application Service persists the changes to the aggregate (calling the save method in a Repository) the infrastructure takes care of publishing the registered events only if the save transaction succeeds.

Let’s see this in action with some code. The domain example is for a Runbook which tracks Tasks, and the use case is assigning a task to an operator.

– Service retrieves and acts on the aggregate.

// RunbookService
fun assignTask(c: AssignTask) {
    val runbook = runbookRepository.findById(c.runbookId)

    runbook.assignTask(c.taskId, c.assigneeId, c.userId) // act on the aggregate
    ...

– Aggregate changes its state and then creates and registers domain events.

// Runbook
fun assignTask(taskId: String, assigneeId: String, userId: String) {
    validateIsOwner(userId)

    getTask(taskId).assign(assigneeId)

    registerEvent(TaskAssigned(runbookId, taskId, assigneeId)) // create and register event
}

Notice that Domain Events are only registered by the aggregate root because it is the one ensuring the integrity of the aggregate as a whole.

The way that the aggregate “registers” events is keeping track of them internally as a list of unpublished domain events.

...
@Transient
private val domainEvents = ArrayList()

protected fun registerEvent(event: EventType) {
    this.domainEvents.add(event)
}
...

– Service calls repository to save changes
After calling the assignTask action on the aggregate the service saves the changes (the “changed” aggregate) using the repository.

// RunbookService
fun assignTask(c: AssignTask) {
    val runbook = runbookRepository.findById(c.runbookId)

    runbook.assignTask(c.taskId, c.assigneeId, c.userId)

    runbookRepository.save(runbook) // save aggregate
}

– Infrastructure publishes all the aggregate unpublished domain events.
This can be done directly with a custom repository implementation and some form of internal pub-subscribe mechanism or with the help of a framework. Later on, I describe how to do this for repositories based on Spring Data.

Unit Testing
Unit testing of the aggregate remains simple with this design, there is no need to mock an event publisher or anything else. Asserting that the aggregate created and registered the right events can be done directly checking the aggregate domain events collection.

    @Test
    fun `can assign task`() {
        val runbook = Runbook(RUNBOOK_ID, RUNBOOK_NAME, OWNER_ID)
        runbook.addTask(TASK_ID, TASK_NAME, TASK_DESCRIPTION)

        runbook.assignTask(TASK_ID, TASK_ASSIGNEE_ID, OWNER_ID)

        assertThat(runbook.domainEvents()).contains(TaskAssigned(RUNBOOK_ID, TASK_ID, TASK_ASSIGNEE_ID))
    }

Domain Events
Here is an example of how the Domain Events for an aggregate look using Kotlin sealed classes.

sealed class RunbookEvent

data class TaskAdded(
        val runbookId: String,
        val taskId: String) : RunbookEvent()

data class TaskAssigned(
        val runbookId: String,
        val taskId: String,
        val assigneeId: String) : RunbookEvent()
...

Using Spring Data infrastructure to Publishing Events from Aggregate Roots
Spring Data repositories have support for aggregate domain events publication. On a call to a repository save() method, Spring will look into the passed aggregate for any unpublish domain events and will automatically publish them via its ApplicationEventPublisher API.

To expose the events the aggregate root needs to provide an accessor method annotated with the @DomainEvents annotation.

...
@Transient
private val domainEvents = ArrayList()
 
@DomainEvents
fun domainEvents(): Collection<EventType> {
    return Collections.unmodifiableList<EventType>(domainEvents)
}
...

Aggregate Root base class
We can reuse across all aggregates the same code for registering events placing it in an AggregateRoot base class.

abstract class AggregateRoot<EventType> {

    @Transient
    private val domainEvents = ArrayList<EventType>()

    /**
     * All domain events currently captured by the aggregate.
     */
    @DomainEvents
    fun domainEvents(): Collection<EventType> {
        return Collections.unmodifiableList<EventType>(domainEvents)
    }

    /**
     * Registers the given event for publication.
     */
    protected fun registerEvent(event: EventType): EventType {
        this.domainEvents.add(event)
        return event
    }

    /**
     * Clears all domain events currently held. Invoked by the infrastructure in place in Spring Data
     * repositories.
     */
    @AfterDomainEventPublication
    protected fun clearDomainEvents() {
        this.domainEvents.clear()
    }
}

Conclusion
Domain Events make explicit what changes within a domain. Use them not only to have a richer model but also a better design, implementation and tests. The different parts of the system can be decoupled much easily and prevent us from having large application services or aggregates.
It also simplifies future integration with other systems, translation from Domain Events to messaging Integration Events is trivial.

References
– Implementing Domain Driven Design, Vaughn Vernon.
– A better domain events pattern, Jimmy Bogard. https://lostechies.com/jimmybogard/2014/05/13/a-better-domain-events-pattern
– Spring – Domain event publication from aggregate roots, Mark Paluch. https://spring.io/blog/2017/01/30/what-s-new-in-spring-data-release-ingalls#domain-event-publication-from-aggregate-roots
– Domain Events vs. Integration Events in Domain-Driven Design and microservices architectures, Cesar de la Torre
https://blogs.msdn.microsoft.com/cesardelatorre/2017/02/07/domain-events-vs-integration-events-in-domain-driven-design-and-microservices-architectures/
– Domain events: design and implementation. https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/domain-events-design-implementation

1 – In a functional DDD style the aggregates: do not mutate state; do not publish or register events; do not throw exceptions. Instead, they return a result type containing the new version of the aggregate and domain events or in case of failure, the result contains the domain errors.

DDD Building Blocks – Value Objects

Value objects are one of the foundational building blocks of Domain-Driven Design. They allow modelling concepts of the Ubiquitous Language that describe, measure or quantify other things in the domain.

It is crucial to understand their characteristics and make more use of them whenever possible instead of trying to model every concept as an Entity or worse, having an Anemic Domain Model where logic related to a value leaks and spreads around services or client code. Values help separating concerns and they are easier to implement, test and maintain.

Examples of Value Objects in a domain could be colour, money, address, e-mail, coordinate, etc. Note that a concept can be an Entity in one domain model and a Value Object in other.

Value Object Characteristics

– Inmutable Conceptual Whole
– Describes, Measures or Quantifies an Entity
– Does not have a unique identity
– Structural equality
– Replaceability
– Side-Effect-Free Behaviour

Implementing Value Objects

Constructors

Value objects are inmutable, do not implement setter methods for its properties, instead provide a constructor with all parameters necessary to initialize its intrinsic state. Parameters may be other objects used to derive internal properties on the new Value.

public class Money {
    private BigDecimal amount;
    private String currency;

    public Money(BigDecimal amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public String getCurrency() {
        return currency;
    }
...

You can find useful, especially for testing immutability, to provide a copy constructor.

    public Money(Money money) {
        this.amount = money.amount;
        this.currency = money.currency;
    }

Use Guard Clauses in the constructor to ensure that the parameters passed are not only valid individually also as a whole initialize a valid Value.

public class FullName {
    private String firstName;
    private String lastName;

    public FullName(String firstName, String lastName) {
        if (firstName == null || lastName == null) {
            throw new IllegalArgumentException("First and last name are required.");
        }

        this.firstName = firstName;
        this.lastName = lastName;
    }
...

Self-encapsulation/delegation

Value objects must not expose setter methods, but internally, we may use and delegate to them to simplify constructors.

Continue reading “DDD Building Blocks – Value Objects”