DDD Decoded - Don't Fear Eventual Consistency

Written on 23 July 2016

Inevitably when talking DDD, someone asks: “It’s all great with those aggregates, events and stuff, but how do I query things?”. Inevitably, the answer is:”Use CQRS” and inevitably, a new issue appears: “You have to account for Eventual Consistency (EC)”, a necessary evil.

But I’m going to say this: The only people worried about EC are CRUD programmers.

Let’s go back in time 100 years

No computers, no CQRS, no EC. Or maybe…. Neah! John and Mary have a shared account at a local bank and it just happens that they decided to withdraw 100$ the same day. Unknowingly, they interact with different tellers, just a couple of minutes apart. Being an epoch without computers, for every operation needing to check an account’s balance the tellers need to talk to another clerk who’s in charge of maintaining the balances. At moment the T, the first teller goes and gets the account balance (it’s 100$). Then he starts to fill in the required paperwork, then handles John 100$. In the mean time, at T+2,the second teller (serving Mary) goes to the back-office clerk and gets the account’s balance. While he’s on the way back, teller #1 goes to tell the clerk that a transaction has occurred and the account balance needs to be updated. Teller #2 returns to Mary, handles the paperwork and gives her 100$. Then he goes to the clerk and tells him to register the new operation, thus updating the account balance.

John and Mary withdraw together 200$, from an account which only has 100$. When the clerk calculates the latest account balance, it gets a negative number. Dang! We have a problem! Does the bank blame it on CQRS and Eventual Consistency, heads will roll because nobody used a Unit of Work? Nope! The bank says: “Meh… yet another opportunity to make money! Start charging interest on the negative balance and notify the client they owe us 100$(+interest)”. Business as usual.

As we can see, Eventual Consistency exists without computers or CQRS. Like rain, it’s a normal phenomenon in the real world. And businesses exist in the real world, so for them EC is just normality, even if a domain expert doesn’t know what the words “Eventual Consistency” mean. And being normality, the business has a solution for this problem.

As programmers, we are trained , almost indoctrinated to pray to the ACID god. We feel fragile if 2 changes aren’t wrapped in a transaction and EC is like the boogie man, we fear it and try to avoid it. But this is just the CRUD mindset, a one trick pony that doesn’t reflect a moderately complex domain.

DDD is about changing our mindset from CRUD, data driven to business driven. And the funny thing is, not only that EC is pretty normal but it’s the default,too. Remember that we try to identify aggregates i.e we’re actively looking for areas, islands that need to be immediately consistent in an ocean of eventual consistency. Those are not in-your-face visible, we have to carefully ‘hunt’ them, in a way proving that only in those cases we need a unit of work.

And maybe that’s one of the biggest things with DDD, the revelation that a model doesn’t really need to always be immediately consistent, like in the CRUD approach; some parts need it, others don’t. Our objective is to identify which needs what.

So, don’t fear Eventual Consistency and try to go beyond the limited CRUD mindset. CQRS works great and usually the delay between sync-ing our event store to a read model is measured in milliseconds. In a world without computers, the delay is way bigger and if the business can survive that, it won’t care about a couple of milliseconds.

Introducing Domain Map - The Domain Modelling Tool

Written on 21 July 2016

Modelling a domain is not easy. And even trickier is how we can jot down our findings in a useful manner. We can write things on post-its, notepad, OneNote or diagramming software. I’ve tried all of those and yet something was missing. I needed a tool optimised for Domain Driven Design modelling and the surrogates were lacking. Something like OneNote is good enough until you need to easily navigate from a relevant concept to another and digramming ends up with something that looks very similar to object oriented design (which is not DDD).

So, I’ve decided to build my own tool, one that will make any domain modeller’s life easier. Enter Domain Map. It’s a MVP (but with enough features) beta at this moment and you only need a Github account to use it. It’s free so give it a try and don’t be shy with feedback or suggestions.

DDD Decoded - The Aggregate and Aggregate Root Explained (Part 3)

Written on 14 July 2016

Coding time! I bet you’ve been waiting for this part for some time. Yes, once we have our model, it’s time to write the code. Let’s start with the Value Objects first.

public class TransferNumber
    {
        public string Value { get; private set; }
        public Guid EntityId { get; private set; }

        public TransferNumber(string value,Guid entityId)
        {
            //validate format based on domain rules

            Value = value;
            EntityId = entityId;
        }
    }

    public class AccountNumber:IEquatable<AccountNumber>
    {
        public string Number { get; private set; }
     
        public AccountNumber(string number)
        {
            //validate format based on domain rules

            Number = number;
            
        }

        public bool Equals(AccountNumber other) => other != null && Number == other.Number;

    }

    public class Debit
    {
        public decimal Value { get; private set; }
        public AccountNumber Account { get; private set; }


        public Debit(decimal value,AccountNumber account)
        {
            Value = value;
            Account = account;
            value.Must(v=>v>=0);//business rule
            account.MustNotBeNull();//ensure VO is valid            
        }
    }
     public class Credit
    {
        public decimal Value { get; private set; }
        public AccountNumber Account { get; private set; }


        public Credit(decimal value,AccountNumber account)
        {
            value.Must(v=>v>=0);//business rule
            account.MustNotBeNull();//ensure VO is valid            
            Value = value;
            Account = account;
        }
    }

Code should be self-explaining, although I bet you’re wondering about 2 things:

  1. Why TransferNumber gets a Guid?
  2. Why there’s no VO implementation for the creation date?

Well, let me start with no. 2. The creation date doesn’t need encapsulation as there are no actual business constraints (in this example). Why complicate the implementation with another class?

TransferNumber acts as a natural id for the Transfer, however, for technical purposes, I prefer to have a technical id too, hence the Guid. We’ll be using it in situations where we need to specify the entity, but we don’t need a full Value Object, for example in messages.

And speaking of messages, here’s our domain change , expressed as a Domain Event

 public class TransferedRegistered
    {
        public Guid EntityId { get; set; }
        public string TransferNumber { get; set; }
        public decimal Amount { get; set; }
        public string DebitAccountNo { get; set; }
        public string CreditAccountNo { get; set; }
        public DateTimeOffset CreatedOn { get; set; }=DateTimeOffset.Now;
    }

A nice, flattened data structure, containing valid data. Valid, because it’s the Aggregate Root (AR) who’s in charge of its generation. Now, I’m going to use a more “exotic” approach for the AR’s implementation.


 public static class Transfer
    {
        public static TransferedRegistered Create(TransferNumber number, Debit debit, Credit credit)
        {
            number.MustNotBeNull();
            debit.MustNotBeNull();
            credit.MustNotBeNull();

            debit.Account.MustBe(credit.Account);

            var ev=new TransferedRegistered();
            ev.EntityId = number.EntityId;
            ev.TransferNumber = number.Value;
            ev.Amount = debit.Value;
            ev.DebitAccountNo = debit.Account.Number;
            ev.CreditAccountNo = credit.Account.Number;
            return ev;
        }
    }

Wait… what?! Static class??? Static function???!!! Say what?! Yeah, it’s called a functional approach. I prefer a hybrid OOP-FP style to code DDD models, especially ARs. Why? Because it’s the simplest implementation. Remember that AR is a role , and the function is the implementation. It makes little sense to make it a full class, when a function is sufficient.

Now, sure, I may have another command case involving Transfer but you see, each model is relevant to one case only and I want my code to reflect that. Basically,I want some boundaries between cases, so the class Transfer is the concept and each static method is an AR enforcing a specific model. Things being static it means they shouldn’t share any state. They’re grouped together only as a convenience.

Our AR makes sure the business rules are respected and then it communicates the change by generating and returning a domain event.

This is not the only way to implement our model, but I like it since it keeps things simple and our code is Event Sourcing friendly. In a future post, when we’ll talk about Application Services, we’re going to see how the AR is used by the service and what to do with the event.

DDD Decoded - The Aggregate and Aggregate Root Explained (Part 2)

Written on 14 July 2016

Part 1 was about the theory, now let’s see an actual modelling example.

To keep things simple, let’s say we’re building a banking app and we’ve identified this desired functionality: “A client can transfer money from one account to another”. Let’s see… are we changing the business state here? Yes, we do and the result of this operation is that the client’s accounts will have different values. So, we need update both accounts: account1.Add(value) and account2.Substract(value) and case closed. Right?

It’s easy to be superficial and to conclude that we need to modify 2 accounts, but let’s take things slowly. We know we are in a “change” operation i.e a command business case, so we need to identify the concepts involved, especially the one in charge of changes. The domain expert tells us that we’re dealing with a transfer between 2 accounts or, to be more precise, with an operation which credits one account and debits the other account. Actually, our business case is to register a money transfer and we’ve already identified 3 concepts: Transfer, Debit and Credit, with the mention that the Transfer is actually defined by at least a Debit and a Credit.

But before we continue, let’s identify the change itself: a new transfer that will be part of the banking system state, and we express that change as a domain event named “Transfer Registered”. We always express changes as “what happened since the last change” and the past tense is important: it tells us that, from a business point of view, the change is already done. From a technical point of view, we need to persist that change, but that’s an implementation detail and the application service’s job. Remember that in the real world, changes just happen and they persist, but in the virtual world we need an explicit “save to database”.

When modelling, the idea is to try to find out the change first i.e the result of the operation and then to identify all the details we need to end up with that change. At this point we have a couple of concepts,but is that all? Well, no… The domain expert tells us that each transfer should be identifiable (hint!) through a unique number, generated according a specific formula and that we need to know the date and time of creation. And the Debit and Credit must be of different accounts.

We have now enough information to determine our Transfer aggregate:

  • composition: Transfer number, Credit, Debit, Creation date
  • rules: All components are required. Credit and Debit target different accounts.

But this is only the top-level view. We need to dig a bit deeper and to identify what each component means, we want to find out their models. Transfer number is a group of numbers and letters that must be unique and are determined according to a business formula. Basically a value respecting some constraints.

Debit is an interesting concept. It’s basically a number that needs to be >= 0 but, it needs to be associated with an account or to be more precise, with an account number. Aha! We found another concept. Account number is a group of numbers generated by a business formula as well. So, Debit is a composite value of an amount and an Account number.

Creditis similar to Debit only the name is different, but that’s enough to be treated as a separated concept which just happens to have the same composition. Creation date is just a simple datetime value.

Now, all these components, are value objects from DDD point of view, because each represents a value with a business meaning and unlike a Transfer they don’t need to have an explicit component that acts as an identifier. Their value is their identity.

We see here how we’ve identified the business concepts, rules and constraints required to make the change and how we’ve organized them into a group of named models. This is our aggregate, the relevant abstraction responsible for controlling the domain state change.

You can have (readonly) fun with this model on Domain Map . Onward to part 3: coding - C#

DDD Decoded - The Aggregate and Aggregate Root Explained (Part 1)

Written on 14 July 2016

For easy reading this topic is split in 3 parts: theory, example modelling and coding (C#) .

A lot of actual and virtual ink has been used to explain this important DDD concept, but as Vaughn Vernon puts it “aggregates are one of the most important DDD patterns and one of the most misunderstood ones”. That’s because they are hard to explain, but once you’ve really understood it, everything becomes easy and clear. But, first you have to accept the fact that DDD is not about coding. Once you know that DDD is just a way to gather domain information and organize it in a technical (developer) friendly manner, you’re ready to grok the Aggregate and its sibling concept, the Aggregate Root.

A model specific to one business case

Everytime we change something we have to make sure we’re making valid changes from the business point of view. Now, the easiest way is to represent things as close as we can to how the business sees them. This means we have to identify the concepts that the domain uses, but more importantly, we need to identify a relevant representation of a concept, relevant for the busines case using that concept.

For example, I can identify the Invoice concept, but what I really need is a representation of it (a model) that I can use in a specific use case like: Create invoice. But what about Cancel invoice? Well, it has its own represenation of Invoice. Each business case needs its own relevant model even if it involves the same concept. We end up with one model per use case but with multiple representations of the same concept. And yes, we want that. Relevancy is a keyword in DDD.

A CQRS intermezzo

Applying the Command Query Segregation (CQS) principle, we ask ourselves: “Am I trying to change things here? Do I need this model to change the existing business state?”. If yes, then our model is actually a Command Model (yes, that’s the C from CQRS) that will contain all he information we need to change that particular part of the business state.

For a Create Invoice case, we need a model of Invoice that makes sense to that business case only! The domain expert will tell you what is the data and the business constraints needed to create an invoice, basically, the components and the rules which together define a new invoice. We’ve identified our Command model which in DDD is called an Aggregate!!

But before we continue…

A real world aggregate example

Let’s say you want to buy a table from Ikea. Do you get a table? Not really, you get a bunch of components and instructions in a box that you have to put together yourself. Let’s say you take out all the wooden parts, screws etc from the box and put them in a pile. Do you have a table? No. You have the components of a table but you need to assemble them according to some rules in order to end up with a table.

The table is an aggregate, that is a group of components ‘held’ together by (assembly)rules, in order to act as a single thing. Both components and rules (Vernon calls them invariants) are what makes an aggregate. A pile of parts doesn’t make a table, just some assembly rules don’t mean anything, we need all of them to create our table.

The aggregate is a model that represents all the relevant information we need to change something. Only that, the information is organized into components, themselves models of other smaller concepts, and rules that needs to be respected. Everytime we want to make changes, we need to identify the aggregate that tell us the relevant components and the rules they must respect.

Identifying an Aggregate

Back to our table example. First thing, we need a busines case that aims to make changes. That’s important, because if you only need to read stuff, you don’t need an aggregate, but just a simple read model and remember that an aggregate is always a command model (meant to change business state). While we don’t really want to build a table, that’s what we need to do in order to have one, so this is our business case: Assemble table (note the semantics).

We want to identify the command business cases as granular as they can be and this means we want one business state change per case. Many times, we think it’s one case when in fact it’s a whole process i.e a sequence of cases. So, we need to pay attention to the domain expert, they can help us identify the boundaries of a business case. Example: a process named “Generate invoice” can involve the cases of “Create invoice” and “Create PDF from invoice”. If we need to change the state of different concepts (“Invoice”,”Pdf Invoice”), then we might deal with a process. And a process can span multiple bounded contexts as well. But we want to identify only one business case (or at least we tackle them one at the time) i.e one relevant business change.

Then we identify the business concept - or domain relationship - that needs to change (being created, updated, deleted) and the relevant model representing it. Again, we want a model which is specific for that business case. So we end up with a bunch of other concepts (we need their models, too!) and business rules. So, for our table, which is the identified concept, we need a representation that tells us what are the important parts and rules required to build it. In this case, we’re lucky, Ikea did the work for us, so our model consists of all the wooden parts and screws, plus the assembly instructions.

An aggregate is an always consistent portion of the business model

An aggregate defines consistency boundaries, that is, everything inside it needs to be immediate consistent. This is important, because it tells us that no matter how many actual changes (state mutations) need to be performed, we have to see them as one commit, one unit of work, basically one ‘big’ change made up from smaller related changes which need to succeed together.

But we don’t actually design things to be in a consistent manner; the fact that we have all those components and rules together tells us that we’re dealing with a group acting as a single unit that needs to always be consistent. This is how we know we’ve found an aggregate.

We can say that we can identify an aggregate either starting from a ‘big’ concept and understand its (busines) composition, or by noticing related concepts and rules that together define an area that needs to be always consistent. Either way, we end up with an aggregate.

A somewhat interesting situation is when we deal with domain relationships, in some cases we need to identify an aggregate for them too. But that’s a topic for another post.

As you see, modelling an aggregate has nothing to with object oriented design, but everything to do with paying attention to the domain expert and really groking the domain.

The aggregate role is very specific

This is an important thing. We need a model because we want to make valid business state changes. However, the purpose of our aggregate is to control change, not be the change. Yes, we have data there organized as Value Objects or Entity references (stay tuned for a post about these) but that’s because it’s the easiest and most maintainable way to enforce the business rules. We’re not interested in the state itself, we’re interested in ensuring that the intended changes respect the rules and for that we’re ‘borrowing’ the domain mindset i.e we look at things as if WE were part of the business.

An aggregate instance communicates that everything is ok for a specific business state change to happen. And, yes, we need to persist the busines state changes. But that doesn’t mean the aggregate itself needs to be persisted (a possible implementation detail). Remember that the aggregate is just a construct to organize business rules, it’s not a meant to be a representation of state.

So, if the aggregate is not the change itself, what is it? The change is expressed as one or more relevant Domain Events that are generated by the aggregate. And those need to be recorded (persisted) and applied (interpreted). When we apply an event we “process” the business implications of it. This means some value has changed or a business scenario can be triggered. More about that in a future post.

You can say the job of the aggregate goes like this: “Based on the input you gave me and business rules that I know, the following business state changes took place: X happened with these details. Do whatever you want with it, it’s not my job, I’m done here”.

The role of Aggregate Root

The companion of the Aggregate is the Aggregate Root (AR) and we already know that we should use the AR to manipulate things in our aggregate. However…

Artifacts everywhere..

In the beginning, DDD was very much mixed (coupled) with OOP. And that’s why we usually have an OOP centric view and patterns names. But today, DDD is about identifying a domain model regardless how it will be implemented; however its OOP roots(ha!) left some artifacts, especially in naming e.g Value Object.

The name “Aggregate Root” make sense in an OOP approach where you have a group of objects and you want only one to be the “root”, the facade representing the whole structure, however, in a more abstract manner, the role of the AR is simply to enforce the aggregate’s business/consistency rules. So today, AR is a role that can be implemented by an object or just a function. If the aggregate means a group of components and rules, the AR is the “guardian” making sure we’re dealing with the right components and the rules are respected. In our real life table example, the AR is the person assembling the table.

And that’s the theory! Onward to a modelling example.