3

Why Domain Driven Design?

 1 year ago
source link: https://yehohanan7.medium.com/why-domain-driven-design-203099adf32a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Why Domain Driven Design?

DDD has gained a lot of popularity in recent days although the idea has been around for more than 10 years. I think it’s primarily because people are starting to notice the correlation between the ideas proposed by the DDD and a certain class of complexity that repeatedly emerges out of softwares built by large scale organisations involving multiple teams.

Although all the modern architectural principles and practices offer solutions to common problems, this peculiar type of complexity that emerges at the heart of software development is usually unaddressed, to which DDD promises to offer a solution.

The goal of this blog is to highlight the type of problems that DDD addresses and give an high level introduction to the solution.

Platonism

0*GDrx7n7TMrkWGCRL

Let’s start by exploring some philosophical ideas that i believe will help you gain some new perspective about DDD.

Plato believes that there exists this realm of abstract objects which are non physical (exists outside space & time) and non-mental, the abstract objects can be perceived through reasoning.

Example: When we talk about a perfect circle, we perceive the idea of perfect circle (which only exists as an abstract object) although any attempt to produce a perfect circle in the physical world will be to some degree imperfect.

The mental or cognitive world is where we see/sense objects in the physical world and discover the existence of the abstract forms in the platonic world, i.e., the idea of perfect circle is discovered, not invented!

In the same way, when we look at a software model or architecture, we are merely seeing a projection of a real system, you may call the real system as the domain (similar to abstract objects)

Domain vs Software Model

The model constructed in the software to represent a particular problem or domain is called, you may have guessed it, the “Domain Model”

The immediate question that comes to mind is, “how accurate the domain model should be?

That’s the same question as “how perfect a circle should be?”, the answer to both the questions are simply “to a degree that is useful to solve a specific problem”.

Yes, there’s no way one could exactly model a domain one-one, but you can always model in a way that’s useful for solving the problem at hand.

Let’s take an example of modelling our own earth.

1*P0nLUYRsOKD9Zy1aL-09Bg.png

Model vs Real

To the right is a real picture of earth, which though real is not very useful.

But to the left is a projection (or model) of the earth called the Mercator map which is very useful in determining the direction of any two locations although the sizes of distorted (look at the size of green land and Africa).

The point is, the Mercator map was modelled for a specific purpose- to have a useful projection that helps sailors to determine the direction!

In essence, Accuracy is not very important, but usefulness is!

Tools for effective Modelling

Now that we agree the importance of modelling a domain/problem, what are the tools at our disposal for effective modelling?

The tools for modelling can be classified broadly as principles, patterns and philosophies.

Design Principles

There are tons of design principles that guides you to model software both structurally and behaviourally.

GRASP principles for instance makes you think and consider how you go about assigning responsibilities to various classes so that you achieve high cohesion on low coupling.

SOLID principles on the other hand is not very different from GRASP, it tries to provide you a guideline to achieve, once again, high cohesion and low coupling, in fact I see SOLID as just refurbished GRASP :-)

Apart from grasp and solid, there are other general object oriented & functional programming principles.

In essence, all principles help you to model your software in a way that’s highly cohesive and loosely coupled- They are the building blocks of a well designed software.

Design Patterns

There are patterns everywhere, a pattern is a thing that repeats…

“house” is a pattern, so is a “village”, “town”, “university” etc.

There are some characteristics that are common among towns, like for example, every town usually will have a town centre, a park, a shopping mall, coffee shop, library, train station etc.

When all the amenities of the town are placed in the right/optimal locations, the town becomes lively and harmonious. Nobody wants a park 5km outside the town nor would you have a bus top right inside the park!

Do you see, there is inherent patterns all around us that repeats, every pattern exists in a context and adds some value to the context.

If you capture the very essence of the pattern with a formal language and give it a name, it becomes very useful in sharing it during communication and also to reproduce it.

This is precisely what Christopher Alexander describes in his books — The Timeless way of Building & The Pattern Language, he catalogues around 250 patterns in his books that you can start using it for both communication and reproduction.

Christopher Alexander had a direct influence on the Gang of four authors who came up with a very popular book called the design patterns. which is, just like the pattern language, a catalogue of around 23 commonly occurring patterns in software.

You may now ask the question “What’s the difference between Principles and patterns?”, I am glad you did, The answer is that patterns emerge from principles.

Principles are the basic building blocks of software models, while patterns are a layer above principles that helps capture, document and share solutions to common problems.

1*TKBd5hSi-eFjbAObt8EyrQ.png

As you can see, above the design patterns there are even higher level architectural patterns like CQRS & Event sourcing.

Design Philosophies

Okay, now we know we have principles & patterns to help us to model our softwares, there are also other fundamental design philosophies out there, but most of ideas from those philosophies can be summarised as “Think in Abstractions”

When you start thinking in abstractions and create abstractions in your code, either top down or bottom up, you will end up producing a good software design.

here are some of the books that talks about the philosophy of software development, these books have had a great impact on how I model/build software.

Limitations of existing tools

Okay, now we are finally at a point to talk about DDD :-)

Quick Recap, we now agree that we have a good lot of principles, patterns and philosophies that enables us to create good software models.

But unfortunately, If you are working in a large organisation that deals with a complex domain, there are still problems that are unaddressed by the principles, patterns & philosophies listed above.

Let’s look at some of the problems that still needs attention.

Disconnected Model

1*OCz4CzrPWMKg61RfKfKkfw.png

If two engineers or teams were assigned a task of modelling a domain using all the known principles & patterns, they will come up with two completely different models! — Not only the models will be different structurally, but also linguistically!

This indicates a big problem, there is no common ground between the teams to unify the model to some degree.

Fractured Language

0*jPo1VOJI8zfV96F_.jpg

One of the reasons for the above problem of “Disconnected Model” is the languages used for modelling, each person in the organisation is free to use any names & terms in their model.

This not only results in a model that’s hard to understand, it creates ambiguity and miscommunications.

For example, if you are building a payment system, what would you call the process where a customer adds a new debit/credit card to his account?
One may call it “Card Linking”, another may call it “Card Authorisation” and another may call it just “Adding new card”.

As an organisation builds more and more systems without agreeing on a common vocabulary, you will see people use different words to describe the same or sometimes completely opposite concepts resulting in a lot of confusion and misunderstanding.

Divided People

1*CBsGx_czAOStrXa9J-PZjw.png

The fractured language is not just a problem among technical teams, it also causes more division in the organisation in general.

The domain experts may have their own language to express certain domain concepts, the vocabulary used by the domain experts may be completely different to the vocabulary used by the technical experts.

This divide is very common in large organisations, you can notice it in any discussions where people from two different groups (tech vs domain) are trying to define a problem or explore possible solutions to the problem.

If one is not able to crisply express the definition of a problem that everyone can agree on, expressing a solution is even harder!

DDD (Key Concepts)

Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.

DDD offers a lot of principles & practices to solve the complexity problems, I will only try to briefly introduce you to the key concepts.

Ubiquitous Language

One of the most important concepts that emerged from DDD is the idea of Ubiquitous language, which tries to address the major problems listed above namely Fractured Language, Disconnected Model and Disconnected people.

0*7A3uxqhEERwz9PYr.png

Ubiquitous language is a practice of building a common shared language between developers and the rest of the organisation- The same language and terms used by domain experts and developers during any discussion should be the same terms used even in the software model.

this allows one to crisply express both the problem and solution without ambiguity, which is a great power!

The language itself evolves as a collaborative effort, which requires a conscious discipline to keep the language updated and managed.

This whole idea may sound simple, but this is exactly the missing element in most organisation, once you make a ubiquitous language as the official of the domain, you will start seeing a consistent usage of it in code, discussions, tests, documents, requirements etc.

Bounded Contexts

The idea of of Ubiquitous language should immediately make you question if it’s realistic to have one global language across a large organisation?

The answer is no! we shouldn’t even attempt to have such a unified global language, it will in-fact work against us and cause more confusions!

Imagine you have two teams one working on a payment system and the other working on order management system, the two systems although may interact with each other are focused on solving very different problems.

Trying to share a common language between the two teams would mean each will try to bend the language to the very specific problem space and hence polluting the language altogether.

0*fqqlGFcAPpU2VgnY

Every word/statement has meaning within a particular context. likewise, every domain concept has a meaning within a (bounded) context.

A bounded context is simply a boundary within a domain where a particular Ubiquitous language or domain model applies.

For example, as shown below you have two bounded contexts (or subdomains) in an organisation, Billing & Marketing.

Both the sub domains deals with a completely different type of problem, however in both the model there is a need to refer to a Customer.

Although the identity of the customer will be same between Billing & Marketing systems, the definition of the Customer various between the two.

The Billing system is interested in the billing address and open invoices while the marketing system is interested in the customer’s contact details and his recent orders.

1*AhsN-SPqvTAGOMdzX0sBlA.png

When I refer to “Customer” within a billing bounded context, it is clear that i am referring to that representation of the customer that contains billing related information, on the other hand if i refer to Customer within a Marketing bounded context it’s clear that i am referring to that representation of the customer that contains contact details and his recent orders. hence there is less ambiguity in the organisation.

This implies that every subdomain (bounded context) has it’s own ubiquitous language and software model.

DDD Principles

All the concepts of DDD we touched so far are high level practices and conventions that help solve mostly organisational problems.

There are also principles that help you to effectively model your domain in code, I will not touch all the principles but few of the key principles.

Entities, Value Objects & Aggregates

Let’s look at an example shown below from an order management system.

1*FWDVq6QZgZvYX6STAyR3Dg.png

Money is a value object, the form definition of value object in the DDD community is: “An object that describes some characteristic or attribute but carries no concept of identity.”

It is very straight forward that Money doesn’t need to have a unique identifier, an amount of $20 can be represented by any instance of the Money class with a value and currency set as 20 & $.

On the other hand, there are classes in your model that requires a unique identifier, those classes are called entities.

The formal definition of an Entity is: “An object fundamentally defined not by its attributes, but by a thread of continuity and identity.”

All entities will have a very well defined life cycle, i.e., it comes to life at a specific point in time and goes through various transformations and may eventually end up in a terminated state.

In the above example, an Order comes to life when a customer places an order and it must have a unique identifier to be useful for the customer to track and make amendments. It goes through various states like pending , shipped etc. And eventually may end up in either complete or cancelled

However, a LineItem of an order, although is also an entity but because we need to identify the exact line item, doesn’t need to be uniquely identifiable outside the context of an “Order”.

i.e., all use cases that requires access a LineItem should first access the Order and then access the line item within the Order — this implies that the LineItem is only required to have a unique identifier within an Order

As you can already see in the example, the Order entity (has a global unique identifier), LineItem entity (has a local unique identifier) and the Money value object together form a cluster of objects called the Aggregate

Also notice that the Order has a special nature, it is the only entity that is uniquely identifiable, which inherently makes it the first point of contact for the outside world to interact for anything to do with the order, hence the Order although an entity, is also called the Aggregate root!

The formal definition: “A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the AGGREGATE, designated as the root. A set of consistency rules applies within the AGGREGATE’S boundaries.”

Repositories

Repositories are abstractions that enables the system to store, retrieve, search a collection of objects (usually aggregate roots)

I have seen cases where people use repository almost like a data access layer, but it’s much more than than, repositories should be always looked at as “Repository of Aggregate roots”

Example: “Repository of Orders”, “Repository of Customers” etc.

This allows you to use the repository interface just like any other domain concept in your domain code, storing the aggregate roots is just an additional responsibility of a repository which is an implementation detail.

But the key here is that Repositories should be treated as first class citizens in your domain model, not as a storage abstraction!

Summary

  • DDD is a cultural shift, it’s a way of thinking.
  • It’s not a technology, it’s a practice.
  • It requires a collaborative effort from across the organisation in order to fully reap the benefits
  • your software model in code along with your tests becomes the source of truth about your domain
  • Uniquitous language is the key!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK