söndag 21 augusti 2016

Building Blocks in DDD

In addition to having a common language with domain experts, the developers need a common language. There are a number of standard patterns that reoccur in DDD. Characterization of these is a vital in the domain-driven design. Sometimes it's pretty obvious which category a particular class belongs to but other times it's not so easy to sort out the different building blocks of a model-driven design. Using standard building blocks helps.

Application Context

In the application-context all the objects that depend on the infrastructure that the application runs in are created. This allows to easily replace parts of the system, such as which database to use. Do not mix this together with the bounded context. The application initiates the application and is a class, while the bounded context is about working on the conceptual level often realized at as packages in Java.
A good way to make the application context is to have a generic context that give singleton instances for domain services, repositories and factories. The generic application context is then specialized to the infrastructure with inheritance, giving for example DAO implementations.

Domain Services

When an operation is not conceptually belong to any object from the beginning, you can implement this through a service. A service interfacing outwardly from a defined context. Domain Services therefore often give the first item out of a defined context, so you can download more entities or valuable objects from the entity that you got.
Domain Services are expressed in the common language and the domain type, ie the method parameters and return values are domain classes. Sometimes the only service interfaces a part of the domain layer, but implementation is part of the infrastructure layer.
If the service is possible to implement using only the domain layer then both interface and implementation can be part of the domain layer.

Application Services

Application Services is responsible for running workflows. They can receive calls from outside to initiate processes. They give the possibility for clients to use the system. These services are typically designed to define or support specific use cases.
Often the data is DTO-serialized and that way a facade to the domain. You do not want to use the objects from the domain directly, because it would create severe maintained dependencies. DTO stands for Data Transport Object and is an important tool for creating data integrity. To translate domain object to DTO objects and vice versa, implement a DTO-converter.


Value Object

A value object is an object that contains attributes but has no conceptual identity. They should be regarded as immutable and temporary outside entities.

Aggregates

A collection of value objects that are joined by an aggregate-root are called an aggregate.

Identity

All items that are not temporary in the domain have an identity. An identity to be able to point out exactly which item that is referred to without further details. Items pointed out by identities called entities. The system must ensure unique identities.

Entity

An object is not defined by its attributes, but rather through their identity. Object attributes can be changed with time, but the identity is always the same. Entities are typically things that are stored in databases.

An entity is almost always an aggregate with an identity. This is often implemented as a Data Object (DO).. This is the form of aggregates stored in the database. The interface is defined by the Repository, but most often implemented in the form of beans in the infrastructure layer.

Repository

Repository is the abstraction of storage in the domain layer. The actual storage is often realized in the infrastructure layer to alternative storage implementations can be easily replaced. The interface for data storage called DAO – Data Access Object.

Factory

Methods to create the domain object are delegated to a specialized factory object. The factory often takes a specification object as data how to build the object. It is common to merge the factory and repository classes and just call them repositories.

Specification

Specifications manages data integrity and initiates the data to the factory. You can see them as an order for a new domain object in the form of an entity.

Considerations

If the domain is simple this system can give a lot of overhead. We have several classes that are similar. Examples of this are that for one entity some classes can be very much alike and look like almost the same aggregates:
  • DO classes
  • Specifications
  • DTO-classes
This is the price we pay for separation of concern, as the layered architecture gives these classes different layers and thus cannot be reused in other layers without breaking the structure.
This can be to much too much overhead for a project that just stores data and in practice is a database.

The benefit is that this system is coherent and scales well. The developers and the domain experts have a common system that is easy to understand and expand.

söndag 14 augusti 2016

Bounded contexts

Now we are entering the main part of DDD: To model the domain.

Context

Context - The environment in which a word or proposition that determines it's meaning.

Bounded contexts are a breakdown of the domain. All major projects covering different sub-models and when the code based on the different models are combined, it can become complex. Communication to and from, and within the team gets confusing. It is often not clear in which context one model should not be applied. The model must be divided in limited contexts with clear interfaces to other parts of the system. Each bounded context shall be independent of the others.

When a number of people working in the same bounded context, there is a risk model becomes fragmented. The more people who are inside, the greater the problems. This breaks down the system into smaller contexts and eventually lose the integration and coherence. There must be a process of merging all code and other artifacts with automated testing. Use the ubiquitous language in order to hammer out a common understanding of the model and concepts. Continuous integration is an essential part of the DDD.

Implementations that have grown during time with no good analysis of the bounded contexts often has a design pattern that could be called BBoM – Big Ball of Mud. The borders between the parts of the server are unclear. Even the responsibilities between the client and the server are entangled. There is no good way to see the protocols.

Context maps

A bounded context leaves some problems in the absence of global perspective. The relationships with other parts of the model may still be vague and constant change.

Developers of other teams may lack knowledge of your context's limits and will unconsciously make changes that blurs the edges or complicating relations. When the connections to be made between different contexts, they tend to bleed into each other.

Identify why each sub model in the project and define its distinct contexts. Name each bounded context and include the name in the ubiquitous language. Describe points of contact between models and their communications. Preferably, the communication is through service-classes and not directly into other defined context.

The context map is often visualized as a simple map which splits the domain into subdomain, and arrows showing which part talks to which part. In the model these often are candidates for submodels, and packages in languages supporting such and even separate micro-services in a large system.