DDD - Maintaining model integrity

Enterprises need big complex software systems and many software developer teams have to collaborate. Often, a project starts with one shared domain model and each team is responsible to design and develop a part of it. The teams might be spread in different buildings or even around the world and communicate sparingly.

For example, the model of an eCommerce system contains modules for Online Shopping, Ordering, Accounting, Inventory Management etc. Team A could be developing Online Shopping and Team B the Accounting modules. In a somewhat trivial scenario, Team A notices that in the shared model there is a concept of an Account. Although, the implementation is not exactly what they need, they introduce a couple of methods and new attributes. Then a few days later Team B discovers a bug in the Accounting calculation related to the code changes of Team A. Evans (2003) argues that is very ambitious to define a single unified model for all software systems of a big project and we need a way to overcome the inevitable complexity.

Hence, it is beneficial to break a big unified domain model down into Bounded Contexts while the relationship between the models could be illustrated with Context Maps (Evans, 2003).

Bounded Context is an explicit definition of the scope of the model with clear boundaries like (Evans, 2003):

  • separate code bases,

  • separate database schemata,

  • separate teams.

There are no hard rules in defining boundaries but all members of a project should understand the boundary rules and inside the boundaries, the model should remain consistent (Evans, 2003). As an example, in an eCommerce system Inventory Management could be a separate bounded context. Another bounded context is Online Shopping which sends requests to inventory for a product's availability.

Whenever an enterprise application is comprised from many models each in its own bounded context, it is beneficial to be able to communicate the whole picture. Context Maps could be documents that identify bounded contexts and their relationships or simple diagrams like the one shown below (Evans, 2003). Brandolini (2009) and Vernon (2013) showcase in more detail the different ways to draw Context Maps.

Example of context mapping and an interaction through an Anti-Corruption Layer (ACL) (Brandolini, 2009; Vernon, 2013).

Bounded contexts could be complete applications deployed in separate servers. One common way to integrate them is by defining an Anti-Corruption Layer (Evans, 2003; Vernon, 2013). This layer provides an interface to communicate to a remote application and translate the retrieved data to a model that the receiving bounded context understands (Evans, 2003). The remote application could be another bounded context, a third party service or a legacy system (Evans, 2003; Peng and Hu, 2007). As shown below, an anti-corruption layer could be organised by a Facade, an Adapter, a Translator and a Service (Evans, 2003; Vernon, 2013). The Facade is a simplified interface to the external system and it is coded according to its model (Gamma et al, 1995; Evans, 2003). The Facade in the figure below, is a simple HTTP client that knows how to send HTTP requests and process the response. The Adapter orchestrates the communication with the remote system using the Facade and feeds the result to the Translator (Evans, 2003). The only responsibility of the translator is to process the response data and instantiate domain objects which are part of the local domain (Evans, 2003). The Service provides the public interface to the Anti-Corruption Layer and its arguments and returned objects are part of the local domain (Evans, 2003). Usually, the Service's interface is defined in the domain model and the implementation of the service is placed in the infrastructure specific modules (Vernon, 2013).

Components of an anti-corruption layer (Evans, 2003; Vernon 2013).

References

  • Brandolini, A. (2009) Strategic Domain Driven Design with Context Mapping. [Online] Available at: http://www.infoq.com/articles/ddd-contextmapping [Accessed 30th August 2013].
  • Evans, E. (2003) Domain-Driven Design: Tacking Complexity In the Heart of Software. Boston: Addison-Wesley.
  • Hu, Y. & Peng, S. (2007) 'So we thought we knew money'. ACM SIGPLAN Object Oriented Programming Systems and Applications Conference 2007. 21-25 October. Montreal: OOPSLA: pp. 971-975.
  • Vernon, V. (2013) Implementing Domain-Driven Design. Boston: Addison-Wesley.

This post is an excerpt of my MSc Thesis titled "Applying Domain-Driven Design in Python - designing a self-hosted Read-it-Later service" (January 2014).

This article was updated on

Related post

DDD - Modelling the Domain - Modules

Software systems could become very complex with a large domain model which makes it overwhelming to see the whole picture. The concept of a Module is a design element in many programming languages (in Java they are called Packages and in C# Namespaces) to divide code for managing complexity and assisting in code reuse. Typically, programming language textbooks promote modules mainly as a code organization tool.

DDD - Modelling the Domain - Services

When designing a Domain Model the prominent modelling paradigm is objects and as a result we are mapping concepts i.e. nouns to DDD building blocks such as Entities and Value Objects. The behaviour associated to those concepts is mapped to methods using verbs. However, there are domain specific functions that we would like to define in the model but cannot be attached into an existing Entity or Value Object (Evans, 2003). Instead of forcing foreign operations into domain objects, Evans (2003) introduced the concept of Domain Services.