Summary of DDD design concepts

1. The aggregate root

In the static modeling of domain concepts, a class of concepts is regarded as aggregation root, which has its own birth and death process, data and behaviors are aggregated on it, and the aggregation root has a unique ID that can represent itself and index to its own data. The Aggregate is a collection of related objects that are accessed as a whole. The Aggregate Root is the Root node of the Aggregate. The aggregation consists of root entities, value objects, and entities. An aggregate root represents an entity, but not all entities should be drawn as aggregate roots, sometimes abstracted as injected data or messages to be processed. Aggregation roots can be of many types and can form hierarchical relationships (or other relationships, mesh or otherwise, but hierarchies are most natural). Each aggregate root can have its own data and behavior. For example, the data of a country could be land, mineral resources, population, GDP, laws, individual data could be age, skill, income, property, etc. The actions of the state can be to change interest rates to introduce policies to ban certain industries, individuals can get jobs, quit their jobs, buy houses, get married, and so on. The collection of data and behavior must serve a particular domain, always abstracting the aggregation root and then aggregating various domain knowledge/terms on it. If most concepts can find a suitable aggregation root and the relationships between the aggregation roots are as simple as possible, this description is probably fine. For example, as described in the above national economic model, the relationship between aggregation roots is complicated, so it may not be a good abstraction. Crucially, there is also no clarity on the purpose for which the system or domain exists (such as analysing whether central bank interest rates need to change, or getting investment advice). The aggregation roots extracted by modeling must be different for different purposes. The foundation of a good model is a thorough understanding of the system. Although the understanding is gradual, the system design should be repeated at the level of aggregation root extraction, for example, three months, the aggregation root model changes, it can be disastrous. So you can start with the obvious ones, and then you can start with the obscure ones, and you need to delay the decision. With aggregate roots, we should avoid creating God classes (or super-long functions). Instead, the data and behaviors on the aggregation root are classified and organized. In different scenarios, the aggregation root participates in different processes, performs different behaviors and assumes different roles. There are only data and behavior at the root of aggregation. Such splitting (or organization) often fails to find the boundary of a single responsibility, and behavior and data may still be very complex. This complexity probably stems from the complexity of the status of the entity itself described by the aggregation root. At this point, status, as a special class of data, should be upgraded to a polymer that needs to be described separately. In addition, the splitting of behavior and data depends on different status. Simply speaking, root participates in a process composed of several different abstract behaviors. Each abstract behavior dependency status can choose a different implementation (implements). The business process, the behavior selection process, and the concrete implementation of the behavior should be described separately (and with different cycles) so that the complexity of the system can be effectively degraded. As for stateless processes, such as digital signal processing, which are strictly constrained by algorithms and formulas, the difficulty of implementation is often not due to concept extraction and complex relationships.

2. How to judge marked fields

The domain is still a collection of businesses, but it’s also data in nature, and marking a domain is really about controlling data access. Data and tables in this domain must be accessed through this domain, not directly across me to access my internal data.

3. How to create good aggregation?

  • Content within boundaries is consistent: only one aggregation instance is modified within a transaction. If you find it difficult to accept strong conformance within boundaries, whether for performance or product requirements, you should consider stripping out separate aggregations and adopting the ultimate conformance approach.
  • Design small aggregations: Most aggregations can contain only the root entity and no other entities. Even if it must be, consider creating it as a value object.
  • Reference to other aggregations or entities by unique identifier: When there is an association between objects, it is recommended to refer to their unique identifier rather than to their whole object. If it is an entity in an external context, construct a value object by referring to its unique identity or attributes that will be needed.

If the aggregation is complex to create, the factory approach is recommended to mask the internal complex creation logic. The relationships of multiple constituent objects within an aggregation can be used to guide database creation, but inevitably there is some resistance. For example, if List< value object > exists in the aggregation, to establish the 1:N association in the database, you need to create a separate table for the value object. In this case, the value object has an ID. You are advised not to expose the ID outside the resource library.

4. The entity

When an object is distinguished by its identity rather than its attributes, it is called an Entity. Example: In the simplest way, the identity information input of the public security system is regarded as an entity for the simulation of people, because each person is unique and has a unique identifier (such as the ID number distributed by the public security system).

5. A value object

When an Object is used to describe a transaction without unique identification, it is called a Value Object. For example, for color information, we only need to know {“name”:” black “, “CSS “:”#000000”}, which avoids the system complexity of identity tracking. Value objects are important, and once you get used to data modeling with a database, it’s easy to think of all objects as entities. Use value object, can do system optimization better, simplify design. It has invariance, equality and substitutability. In practice, you need to ensure that a value object cannot be modified after it is created, that is, no external modification of its properties is allowed. In the integration of different contexts, there will be a common concept of model, such as the commodity model will exist in various contexts of e-commerce. In the context of an order, it is a good idea to treat the item object as a value object if you are only interested in snapshots of the item information at the time of the order.

PS: Use value objects with caution

In practice, we find that although some domain objects conform to the concept of value objects, many original definitions will change with business changes, value objects may need to have a unique identity in business meaning, and the reconstruction of such value objects often requires high cost. Therefore, in particular cases, we should also weigh the selection of domain objects according to the actual situation.

Bounded context

A specific responsibility defined by display boundaries. The domain model exists within this boundary. Within boundaries, each model concept, including its properties and operations, has a special meaning. A given business domain can contain multiple bounded contexts, and to communicate with a bounded context, you need to communicate by displaying boundaries. The system is decoupled by defined bounded contexts, and each context is tightly organized internally with clear responsibilities and high cohesion. A nice metaphor: the cytoplasm exists because the membrane defines what’s in the cell and what’s out of the cell, and determines what can pass through it.

7. Mapping between bounded contexts

  • Partnership: A relationship in which two contexts work together so closely that both rise and fall.
  • Shared Kernel: A model in which two contexts are partially Shared.
  • Customer-supplier Development: Organized upstream and downstream dependencies between contexts.
  • Conformist: The downstream context can only blindly depend on the upstream context.
  • Anticorruption Layer: One context interacts with another through adaptations and transformations.
  • Open Host Service: Defines a protocol to allow other contexts to access this context.
  • Published Language: Commonly used with OHS to define protocols for open hosting.
  • Big Ball of Mud: Mixed context with unclear boundaries.
  • “SeparateWay” : Two separate contexts.

8. Field services

Some important domain actions or operations can be categorized as domain services. It is neither an entity nor a category of value objects. When we adopt the microservices architecture style, all the external exposure of domain logic needs to be done through domain services. For example, the business logic originally exposed by the aggregation root also needs to rely on domain services.

9. Domain events

A domain event is a modeling of activities that occur within a domain.

Term 10.

PS: Partnerships ACL: Anticorruption Layer DC: Data Coupling OHS: Open Host Service

11. Strategic and tactical modeling of DDD

Strategic Modeling:

  1. Bounded Context
  2. Context Mapping

Tactical Modeling:

  1. Aggregation – Aggregate

  2. Entity – the Entity

  3. Value Objects -Value Objects

  4. Repository – the Repository

  5. Domain Services -Domain Services

  6. Domain Events -Domain Events

  7. Module – Modules