4 min read
Software Architecture Hour: Domain Driven Design with Jessica Kerr

Source: Jessica Kerr

Systems Thinking

Focus on feedback loops and the circle of causality.

The circles of causality can either be virtuous or villainess.

Developers and software are not independent. They need each other to continue to work and improve to get better.

Neil – Getting feedback loops, the software doesn’t have an end. So getting feedback loops to give us valuable information on our impact on software. That allows us to measure our impact and adjust on our input.

Changing software can be a compounding activity. For example, if you don’t deploy software and you keep changing software, then when you do deploy it’s a massive undertaking. Which is error-prone and usually takes a long time. Instead, if you deploy each change separately, the changes are small, low risk, and incremental. It’s much easier to deal with, even when there is an error.

In systems thinking, if you can get the pieces to work together more harmoniously, it’s actually less work.


The two go-to books for System Thinking:

The best overall System Thinking book is called Donella Meadows, “Thinking in Systems”. Jerry Weinberg, “Quality Software Management Vol. 1.”

You want the domain complexity in your software, not the code or software complexity.

The deep insights from Domain-Driven-Design:

  1. You want all the business complexity. That’s the point of the software.
  2. Drawing boundaries in software, Eric Evans calls them Bounded Contexts. Using the ubiquitous language, gives you the ability to reason with the code and change it correctly. This also feeds back into the clarity of the model and engineer’s understanding of the code. You can’t have a unified language across the entire company, you have to scope the language to the bounded contexts.


Avoid semantic delusion. Words that don’t anything or are so broad, it’s hard to get a specific meaning when used. Examples of this are words like Refactoring or Agile.


When Event Storming, look at the edge use cases, not just the happy path, looking at edge cases will strengthen your software.

When talking to other developers or architectures use precise language.

Always strive to shorten feedback loops.

When the business is figuring out the domain, we(developers) can drive
out the imprecisions by asking clarifying questions.


In a rewards system that is based off the receipt, everything in the system needs to have access to the receipt. What happens in a lot of systems is one receipt model is created that has everything on it and it’s passed to each service that needs it. The problem with this, is now you’ve created a god object and the entire system knows about this one object and has a dependency on it. So if it needs to change, the entire system is impacted.

A better approach is to create different versions to the Receipt object, with only the data needed for the service. So if the service changes which requires a change to it’s copy of the Receipt model, those changes don’t impact the ENTIRE application.

The idea the everything needs to be reused through out the entire system, is the opposite of low coupling. High reuse means you have to couple to everything. Low coupling mean low reuse, which means some places will see redundancy. Which is fine, code duplication is ok, especially outside the bounded contexts.


DDD says “Don’t repeat yourself within a bounded context.”

If you do need to share functionality between bounded contexts, it needs to be a third-party service/library.

Eric Evans DDD book. Reading it from an Architecture Perspective, read the first 3 chapters and then chapter 5, and then to strategic design.


Don’t focus on technology problems. If someone releases a solution that solves one of your problems, consider using it. If it’s not one of your core competencies, there is no need for you to have ownership over that functionality.


Don’t build it yourself if it’s not unique.


Domains aren’t entity mappings but are workflows. The behaviors are essential.