Sunday 4 December 2016

Getting 'Domain' back in DDD

I was first introduced to Domain Engineering through Jim Coplien's book on 'Multi paradigm design in C++'.  It was around early 2000s, when Object Oriented Programming was considered synonym for professional and good programming.  I was C++ developer then, and a fan of C++ STL. There was nothing OO about STL, a library I liked was at the time. Around the same time Aspect Oriented Programming was becoming popular with frameworks like AspectJ and later Spring support for Aspect oriented programming. There was nothing Object Oriented about this as well.
So, I thought, there must be some fundamental design  thinking, more fundamental than Object Orientation which needed to be used for design.
I found Jim Coplien's book on Multiparadigm Design, and was fascinated by that. The concepts of Commonality and Variability, and mapping them to  solution domain based on the the programming language or tool we use was perfect. It allowed me to broaden my design thinking.

Domain Engineering
The concept of domain engineering is thinking in terms of domains, instead of applications. Wikipedia has a nice description of this https://en.wikipedia.org/wiki/Domain_engineering. I am using following diagram from Wikipedia for quick reference.

The idea is to think and model about generic domains/sub domains instead of thinking in terms of specific application requirements.
So, if we are working on building web applications, techniques for implementing representations can be a domain in itself. Implementations can vary to use different libraries like freemarker, velocity or stringtemplate. Designing for allowing various different templating mechanisms gives lot more flexibility. 
If we are communicating across services. Communication methods can be domain in itself. Keeping design flexible to use different communication methods helps.
At a business domain level, if we are building a core banking system, finding commonalities/variabilities across concepts like Account help leveraging the same implementation to use across multiple banks in multiple countries. Getting these domain concepts implemented right with correctly identified commonalities and variations help reusing the components across multiple implementations.

DDD, the problems.

Domain Driven Design is the term popularized by book by Eric Evans with the same title, 'Domain Driven Design'. The first few chapters of the book are very appealing. The concept of 'Ubiquitous Language' is great. Reflecting domain model in code using the ubiquitous language of the domain was a good advice I follow in my code. It maps well to my understanding of domain engineering as well.

There are some issues with technical implementation patterns though. Entities, Value Objects, Modules, Aggregates are all good guidance. But a lot of these findings come iteratively. Its good to know these, particularly in the context of Ubiquitous Language and keeping Domain concepts separate from User interface or persistence mechanisms. But there are more things in domain, than just  Entities, Value Objects, Repositories and Services. But the problem is not really this. The conceptual problems start when DDD gets discussed in the context of MicroServices, which most people today talk about.

Microservices and DDD.

In last few years, since the dawn of Microservices Architecture,there is a surge in discussions about Domain Driven Design.
The discussion resolves primarily about Bounded Contexts, Aggregates and Eventual Consistency.
Most DDD discussions mapping it to Microservices world keep on using DDD technical design patterns like Aggregates, Aggregate Roots, Entities, Value Objects and so on.
Splitting application into multiple services is the decision is not only dependent on domain/subdomain split. Following can be major drivers for system partitioning.

      1. Autonomy of teams working on different features
      2. Different rate of change of parts of the system.
      3. Non functional aspects, particularly scalability

That domains and subdomains provide a good guidance for splitting is just one aspect. e.g. Its generally better to not split domain across teams. If you are developing for travel domain, shopping and booking can be sub domains. Its OK to split teams and so software components for these two sub domains. Splitting teams working on single subdomain across architectural units might not be a good idea. But then if the architectural units can evolve independently like Android Mobile UI, Web UI, IOS UI,  and core services, each can be a separate team working on independent code base.

So based on my observations and experience , the difficulties people find in DDD is mostly because of these implementation patterns which do not necessarily map to 'Domain' concepts.
In fact I see a danger where developers on the team all talking in terms of these technical implementation patterns like Bounded Context, Aggregate, Entities, Value Objects etc.. which is neither domain specific nor ubiquitous and might confuse domain experts.