At Intergiro we want to improve our craft and increase our success when delivering projects. This means implementing software that not only correctly models our clients’ business needs but also performs at scale, using the most efficient software architectures and approaches.
There’s a lot of complex business requirements that we have to deal with and there are techniques that help with this task. One of them is called Domain Driven Design (DDD).
DDD is a set of tools that assists in designing and implementing software that delivers high value, both strategically and tactically. It can help teams design useful software that accurately models the business’s unique operations.
When modelling a domain, it is important to define a common language for it. In DDD this is called the ubiquitous language. Every term in the ubiquitous language has a well-defined, unique meaning within the boundaries of the (sub)-system under design. This boundary is called “bounded context”.
Intergiro’s platform is multifaceted and consists of multiple bounded contexts. We call them ‘Streams’.
When we start designing our software from a database-centric view, we tend to build big database entities that contain all possible attributes. We use these entities in multiple features of the software. For example, we can start building BaaS corporation functionality inside Direct corporation. It is easy to build such big entities, but they tend to be hard to use.
In DDD we design two different bounded contexts for BaaS and Direct products. Corporates are represented differently in each context, and have different attributes and functionalities. The advantage of this approach is simpler entities with fewer attributes and functionalities, which also leads to fewer concurrency issues.
A drawback is the need to synchronise contexts that may be complex to achieve. For example, the BaaS and Direct contexts would like to share customer KYC information. There are multiple solutions for synchronisation available both from DDD itself in the form of integration patterns as well as related techniques such as Domain Events and Eventual Consistency.
Aggregates and Modules
Two more concepts that are important patterns of strategic modelling in Domain Driven Design are Aggregates and Modules. Both aim to organise the other building blocks of the domain model inside Bounded Context.
Aggregates group multiple database Entities together into one cohesive unit. What is special about this unit is that within a single Aggregate, all composed parts must be consistent, according to business rules, when the controlling transaction is committed to the database.
The reasons for the transactional boundary are business motivated, because it is the business that determines what a valid state of the cluster of Entities should be at any given time. In other words, if the Aggregate was not stored in a whole and valid state, the business operation that was performed would be considered incorrect according to business rules.
Modules are used to organise the elements of a domain model on an even higher level than Aggregates. They provide a different, higher-level view on the model and code where details are hidden. Without those details in the way, the cognitive load is reduced and we can reason about connections between the groups of domain elements.
The domain module is a container for the other domain objects. It groups them into highly cohesive units. Objects within the module should be closely related to the domain concept it describes. Between modules, the main goal is to aim for low coupling to reduce the mental load and promote predictability when working with its elements. By naming the modules according to the ubiquitous language, we can tell the story of the system on a higher level.
Hopefully this will give you some more ideas on how to go about structuring domain entities inside a particular Bounded Context.