Introduction
Domain-driven design consists of a set of patterns for building enterprise applications from the domain model out. An interesting software design technique to understand and solve complexity is Domain Driven Design (DDD). Domain Driven Design advocates modeling based on the reality of business as relevant to our use cases. As it is now getting older and hype level decreasing, many of us forget that the DDD approach really helps in understanding the problem at hand and design software towards the common understanding of the solution. When building applications, DDD talks about problems as domains and subdomains. It describes independent steps/areas of problems as bounded contexts, emphasizes a common language to talk about these problems, and adds many technical concepts, like entities, value objects and aggregate root rules to support the implementation. Sometimes these technical rules are perceived as hard barriers implementing the DDD, but at the end, people tend to forget that the important part is to organize code artifacts in alignment with business problems and using the same common, ubiquitous language.
Bounded Contexts Designed as Service Applications
The architectural style I would like to talk about is very similar to microservices. It is about separating the monolithic applications into multiple stand alone service applications or developing them separately from the beginning with the help of bounded contexts, a DDD concept.
There are many resources which highlight pros of having more granular services explained part of microservices narratives. Increasingly, there are more articles, blogs and other content available about the pitfalls and the kind of safety nets that you should have before or during the transition to granular services. I will try not to repeat the benefits of microservices or other supporting elements that you need to have, to migrate into such an architecture. Instead of emphasizing on the "small sized" nature of the resultant services, I would like to emphasize on how we can separate these better by applying domain driven design concepts.
Let's use a real-world example to materialize our ideas - a debit/credit card acquiring domain. This domain could be (as is the case many times, unfortunately) realized as a set of monolithic applications. The only reason that we have multiple applications is due to the hard technical limitations (such as a desire to execute batch processes) in different applications.
Most successful architectures that I have seen, recognize that integrating through databases is a bad practice, as it makes the boundary between technical application and business responsibility blurry, allows business logic to leak into the database and prevents horizontal scaling by adding more application servers. So the evolution to a better architecture happens in the form of service integration of monolithic applications.
Now the boundaries between applications are clearer. But as you can see, there are still hidden DB interations, this time happening inside the individual applications. I call them hidden as they are generally hard to notice at first. As time passes, tangling of the code will make originally- separated business processes related artificially and introduce more friction in business development, as this co-location requires joint deployment of separate features which potentially can slow down the pace.
Domain modeling helps to identify and separate tangled implementations, if you are lucky to have a domain model to guide you. If you don't already have a domain model for an existing application (which is generally true in most cases), instead of going through the code to understand the different responsibilities, building a domain model and mapping the capabilities to the application at hand can probably be a better approach. This will both save time and prevent the risk of being lost in the weeds of detail. Also, if there is a gap between the business and the development team (which could be the major reason that the domain model didn’t exist in the first place), talking about the domain model and mapping to the capabilities of existing applications will help narrowing this gap.
The next step in our design evolution is to reflect domain boundary separation to our architecture as well as bounded contexts. A domain having more than one bounded context means that there can be multiple service applications which operate in the same domain. With the proper domain model in place, potential separation points are more visible, which allows us to benefit from potentially more granular applications (benefits such as separate release and versioning, potential to have more capability-driven pure service endpoints etc. Most of these have already been discussed in microservices articles). While much of the microservices discussion centers around technology agnosticism and development discipline (avoiding / breaking the monolith), a very valuable item for the applications that most of us work on is the domain and design aspect. Once transitioned to a microservices architecture (with a help of domain model), DDD and more granular services can work in synergy to support each other.
This will also provide a level of independence to the teams, more refined capabilities of services and more decoupled interactions as explained in many microservices texts.
Also, as can be seen in our sample credit card payment acquiring domain, this is not the most granular separation we could have with our services. Instead, this is the most meaningful separation guided with our domain knowledge. The emphasis is not on the size, but instead on the business capabilities. I believe this is the "SOA done right", as is said in many circles.
No comments:
Post a Comment