CHAPTER 5- Preserving Model Integrity

This chapter is about vast projects which require the consolidated endeavors of several teams and issues faced when several teams works on small modules of a code. It brings about change of the model, and it is possible that this change will break application functionality.

This problem can be approached by not attempting to keep one big model that will break apart later, we ought to intentionally isolate it into a few models

Properties of a Good Model:

  • A model should be consistent (interior consistency of a model is called unification.)
  • A model should contain invariable terms.
  • No inconsistencies or contradiction.
  • Each model should have a clearly delimited border, and the relationships between models should be defined with precision.

Set of techniques used to maintain Model Integrity

Ubiquitous language

The Ubiquitous Language ought to be the main language used to express a model.

Bounded Contexts

Each model has a context which is implicit. When working on huge application need to make different contexts for different models. The main step is to define context of each model. A Bounded Context (not a module) provides the logical edge inside of which the model develops. Need to define boundaries and relationship between different models.

Continuous Integration

The bigger the team, the bigger the possibility of model to fragment. Nonetheless, breaking down the system into ever-smaller contexts in the long run loses an important level of integration and coherency. We require a procedure of integration to ensure that all the new components which are included fits perfectly into the rest of the model, and are implemented effectively in the code. We need a procedure used to merge the code.

Solution:

  • Merge code as frequently as possible.
  • Have a good suite of automated tests.
  • Continuously discuss, update and extend the ubiquitous language.

Context Map

An enterprise application has multiple models, and each model has its own particular Bounded Context. It is advisable to utilize the context as the basis for team organization. While each team works on its own model, it is useful for everybody to have an idea of the general picture. A Context Map is an archive which outlines the different Bounded Contexts and the relationships between them. It can be a diagram, or it can be a written report. Everybody should know the boundaries of each context and the mapping amongst contexts and code.

Common practice is to define a context, create modules for each context and use a naming convention to indicate context each module belongs to.

Shared Kernel

The purpose for the Shared Kernel is to decrease duplication, yet at the same time keep two separate contexts. Both teams may modify the portion of a code, and they need to integrate the changes. A test suite ought to be set up, so every change done to the piece to be tried right away.

Sooner or later, for reasons unknown, we might decide that different contexts should share a subset of the model implementation. This implies they might share code, data representation (entities) and data storage. This gives us the benefit of allowing us to not require any translation layers or anti-corruption layers

Customer Supplier Teams

There are times when two subsystems have a special relationship: one depends a great deal on the other. Context is different however the processing result of one system is fed into another. They do not have a shared kernel, may not be conceptually correct or technically not possible.

There is a tight relation between these two modules. The client module relies on upon the supplier module. This implies the supplier can not change openly, as these progressions could break the client. The teams responsible for these modules must work intently to coordinate the evolution of these modules.

Conformist

When we have a client/supplier relation be that as it may, for reasons unknown, we don't have the essential coordination and motivation of the supplier to coordinate with the client team, the client team is all alone when dealing with the supplier evolution.

The client team has couple of options. The most obvious one is to isolate from the supplier and to be totally all alone.

We can chose from the above options,

  • Abandon the supplier:[SEPARATE WAYS]
  • Assume full liability for translation:[ANTI-CORRUPTION LAYER]
  • Embrace the foreign model: [Conformist]

Anticorruption Layer

We often encounter circumstances when we make an application which needs to interact with legacy software or a separate application. There are different ways for our client framework to interact with an external one. One is via network connections. Another technique for interaction is the database. An ANTICORRUPTION LAYER is a method for linking two BOUNDED CONTEXTS. The motivation behind why you might utilize an anti corruption layer is to create a little padding between subsystems with the goal that they don't spill into each other.

Implementation:

See the layer as a Service from the client model.

Separate Ways

We should only integrate sub-systems if we really, REALLY, need to. We should, as much as possible, define bounded contexts that are completely independent, completely disconnected from other bounded contexts, and therefore have no need for integration.

Open Host Service

When we try to integrate two subsystems, we usually create a translation layer between them. This layer acts as a buffer between the client subsystem and the external subsystem.

If a bounded context connects to many other bounded contexts, we will be putting a lot of effort on building translators. Solution is to see the external subsystem as a provider of services. If we can wrap a set of Services around it, then all the other subsystems will access these Services, and we won’t need any translation layer.

To prevent such issues, we can simply create a coherent and clean API in our Bounded Context, supported on a set of Services that provide the functionality needed by the other Bounded Contexts.

Distillation

A large domain has a large model even after we have refined it and created many abstractions. It can remain big even after many refactorings. In situations like this, it may be time for a distillation. The idea is to define a Core Domain which represents the essence of the domain. The byproducts of the distillation process will be Generic Subdomains which will comprise the other parts of the domain.

Published language

Data must flow through the above Services, in some language they can all understand. This language is a textual representation of the data, its a Data Interchange Language. XML or JSON

Important Chapters in Domain Driven Design