Domain Driven Development Patterns

DDD Analysis Patterns

Knowledge Crunching

Problem: How does a developer gain sufficient knowledge about an application domain?

Hold knowledge crunching sessions with domain experts, ask questions, listen to their answers, draw diagrams, take notes.

Start from use cases. Look beyond requirements. Understand the intent of a use case. Explore scenarios.

Do your homework. Read text books, look for existing domain models, read company documentation, look at domain standards.

Ubiquitous Language (UL)

Learn and use domain vocabulary throughout the development process. Use domain vocabulary to name packages, classes, operations, and attributes.

Domain Distillation

Most domains are too large and complex for a single model. Parse the domain into sub-domains that can be modeled separately.

Sub-domains may be defined by products, services, fields, purposes.

Identify the core domain-- the domain crucial to the enterprise. A core domain may depend on multiple supporting domains. They are necessary, but are not the main business of the enterprise. Core and supporting domains may depend on generic domains. These are domains that occur across a spectrum of enterprises.

Example: E-store

·       Core domain: online sales

·       Supporting domains: shipping, banking, inventory

·       Generic domains: web server, chat server,

Iterative Improvement

A domain model is created iteratively. Simplifications, misunderstandings, and gaps are gradually replaced. Kill your darlings. (A writer's term for abandoning bits you may love but that no longer fit.)

DDD  Design Patterns

Bounded Contexts

A sub-domain belongs to the problem space. A sub-domain may require multiple models. A bounded context belongs to the solution space. Its purpose is to isolate a model from other models.

Problem:

A domain model is often not just a single model, but several models, one or more for each sub-domain.

Models can grow in complexity.

Multiple teams working on a single model can lead to inconsistencies.

Terms can have different meanings in different parts of the model. For example, a customer might be a corporate customer in one part of a model and a retail customer in another.

Replacing legacy models can be time consuming.

Solution:

Each model should have a bounded context. A model's context is its scope within a (sub-) domain. A bounded context is a context encapsulated by a set of responsibilities and definitions.

Example:

The term "product" might have slightly different meanings in different sub-domains: sales, inventory, shipping, and marketing. This could mean different operations and attributes. Rather than lumping all of them together in a single bloated class, we can create multiple product classes, each in its own package: sales.Product, inventory.product, shipping.product, and marketing.product.

Context Map

A context map sketches the relationship between different bounded contexts (shown here as packages):

Each BC contains one domain model. (If a domain model gets too big, then we can divide it into sub-models each with its own BC.)

Bounded contexts may contain other BCs.

The dependency arrows show which BCs use which other BCs.

Changes to the upstream provider may precipitate changes to the downstream client.

Each dependency implies some form of communication such as shared memory (useful if there is a common core) or message passing.

For example, an employee model (position, contact info, demographical info, benefits, etc.) might be shared by payroll and org structure.

Layered Architecture

The presentation layer contains classes related to interfacing with actors: users, databases, clients, servers, etc.

The application layer contains classes related to implementing use cases.

Domain layer classes represent domain entities and their behavior: accounts, purchase orders, employees, etc.

The infrastructure layer contains architectural classes: command processors, message brokers, object managers, etc.

(Notice that the lower the level, the more reusable a class is, unless there is a misguided dependency on a higher level class.)

Model-Driven Design (MDD)

MDD is a pattern listed in several texts. The distinction between MDD and DDD (Domain-Driven Design) is muddy. Also, MDD is easily confused with OMG's widely reviled Model-Driven Architecture or MDA. In my view the key insight is that the domain model evolves into the domain layer of the design model through a series of iterations. The goal of the early iterations is to faithfully represent the application domain. MDA refers to the later iterations, where the goal is modeling the implementation.

There is a tendency to abandon the domain model once the requirements are understood, because it is vague, incomplete, ambiguous, and with no concessions toward implement-ability. MDD resists this urge. Gaps in the domain layer need to be filled by returning to analysis to learn how to correctly plug the gaps. Often this can expose developers' misunderstandings.

Domain Layer Associations

Domain Layer Associations

Domain Layer Stereotypes

Domain Layer Stereotypes

Reference

The following paper gives a fairly complete account of the DDD patterns:

Eric Evans, DOMAIN-DRIVEN DESIGN, Addison-Wesley, Ó Eric Evans, 2004.