Key points to design application following DDD

byGinkSun, 26 Mar 2023

1. Step by step:

1.1. Identify the domain:

The first step is to identify the domain that the software system will model. This involves understanding the business problem that the software is meant to solve, as well as the key concepts and rules of the domain.

1.2. Define the ubiquitous language:

Once the domain has been identified, it is important to establish a shared language between the development team and the domain experts. This language should be used consistently throughout the project to ensure that everyone has a clear understanding of the domain and its key concepts.

1.3. Create a domain model:

Based on the ubiquitous language and the key concepts of the domain, a domain model should be created. This model should capture the essential concepts, relationships, and rules of the domain, and should be expressed in terms of domain entities, value objects, aggregates, and services.

1.4. Use bounded contexts:

In large systems, it may be necessary to divide the domain into bounded contexts, each with its own model and language. Bounded contexts help to isolate complexity and clarify the relationships between different parts of the system.

1.5. Implement the domain model:

Once the domain model has been defined, it can be implemented in code. This involves creating classes and interfaces to represent the domain entities and value objects, as well as services to implement the domain logic.

1.6. Use test-driven development:

To ensure that the domain model is correct and working as expected, it is important to use test-driven development (TDD). This involves writing tests that specify the behavior of the domain model, and then implementing the model to make the tests pass.

1.7. Use event sourcing:

Event sourcing is a technique that can be used to capture the state changes of a domain model over time. Instead of storing the current state of the model in a database, event sourcing records the events that led to the current state. This can make it easier to implement CQRS and other patterns that require a clear separation between reads and writes.

2. What is Ubiquitous language?

Ubiquitous language is a key concept in Domain-Driven Design (DDD) that emphasizes the importance of using a shared, well-defined language between domain experts and developers. The idea is to create a language that is used consistently throughout the development process, from the domain model to the code and the user interface.

Here's an example of how ubiquitous language might be used for a simple e-commerce application:

1. Identify the domain:
   The domain for the e-commerce application is online shopping.
2. Define the ubiquitous language:
   The development team and domain experts agree on a set of terms and phrases to describe the key concepts of the domain. For example

  Customer: A person who creates an account on the website to purchase products.
  Product: A physical or digital item that can be purchased on the website.
  Cart: A temporary storage for items that the customer intends to purchase.
  Order: A record of a customer's purchase, including the items purchased, the total price, and the shipping information.
  Checkout: The process of finalizing a purchase and entering payment and shipping information.
3. Create a domain model:
   Based on the ubiquitous language, the development team creates a domain model that represents the key concepts and relationships of the domain. For example

  Customer: An entity that has a unique identifier, a name, an email address, and a password. A customer can place orders and has a shopping cart.
  Product: An entity that has a unique identifier, a name, a description, and a price. A product can be added to a shopping cart or purchased in an order.
  Cart: An aggregate that contains a list of items that a customer has added to their cart.
  Order: An aggregate that represents a customer's purchase, including a list of items, a total price, and shipping information.
  Checkout: A service that is responsible for finalizing a purchase and creating an order.
4. Use bounded contexts:
   The e-commerce application might have several bounded contexts, such as the customer context, the product context, and the order context. Each context has its own language and model, and communicates with other contexts through well-defined interfaces.

By using ubiquitous language, the development team and domain experts can create a shared understanding of the e-commerce domain and its key concepts. This can help to avoid misunderstandings and improve the efficiency of the development process.

3. Any rule to decide Bounded contexts?

There are some guidelines and principles that can help to identify and define bounded contexts in a domain-driven design (DDD) approach.

  • Focus on business capability: A bounded context should represent a specific business capability or area of responsibility within the larger domain. It should have a clear purpose and set of goals that are focused on delivering value to the business.

  • Define clear boundaries: A bounded context should have well-defined boundaries that separate it from other contexts within the domain. This might include defining a clear interface or contract for communicating with other contexts.

  • Use a common language: Each bounded context should have its own ubiquitous language that is specific to its business capability. This language should be used consistently throughout the development process to ensure clear communication between domain experts and developers.

  • Encapsulate complexity: A bounded context should encapsulate the complexity of its business capability, hiding implementation details from other contexts within the domain. This can help to reduce dependencies and improve the maintainability of the system.

  • Ensure scalability: A bounded context should be designed to be scalable, so that it can accommodate changing business needs and handle increasing amounts of data or traffic.

  • Consider the team structure: A bounded context should align with the team structure, so that each team can focus on a specific area of responsibility and work independently within their context.

4. Things we have to care in a Bounded context?

  • Entities and Value Objects: A bounded context should contain entities and value objects that represent the core business concepts and logic. These should be designed to encapsulate the complexity of the business logic and provide a clear and understandable model of the domain.

  • Aggregates: Aggregates are clusters of entities and value objects that represent a transactional consistency boundary. They should be designed to ensure that the business rules and invariants are enforced correctly.

  • Domain Events: Domain events can be used to communicate changes or updates within a bounded context to other contexts or systems. They should be designed to carry only the necessary information and be triggered by meaningful business events.

  • Repositories: Repositories are responsible for managing the persistence of entities within a bounded context. They should be designed to encapsulate the persistence logic and provide a clean and simple interface for the rest of the system to interact with.

  • Services: Services can be used to encapsulate complex business logic or orchestrate interactions between entities and value objects within a bounded context. They should be designed to minimize complexity and ensure that the business rules are enforced consistently.

5. What are Entities and Value Objects? And how to define them?

5.1. Entity:

An entity is an object that has a unique identity and can be tracked over time. It represents a real-world concept that has continuity and persistence. For example, a Customer can be an entity in an e-commerce system. An entity can have attributes and behaviors, and its identity can be represented by a unique identifier (ID). The identity of an entity should not change even if its attributes change.

5.2. Value Object:

A value object is an object that does not have a unique identity but is defined by its attributes. It represents a real-world concept that has no identity of its own and can be replaced by another object with the same attributes. For example, a Money value object can be used to represent a monetary value in an e-commerce system. A value object can have attributes and behaviors, but its identity is determined by its attributes.

When deciding whether a concept should be modeled as an entity or value object, there are several factors to consider:

  • Identity: Does the concept have a unique identity that needs to be tracked over time? If yes, it is likely an entity. If not, it may be a value object.

  • Mutability: Is the concept immutable or mutable? If it is mutable, it may be an entity. If it is immutable, it may be a value object.

  • Composition: Does the concept consist of other concepts? If it does, it may be an entity. If it is composed of other value objects, it may be a value object.

  • Equality: Does the concept need to be compared for equality based on its attributes? If yes, it is likely a value object.

  • Lifecycle: Does the concept have a lifecycle or a set of transitions that it goes through? If yes, it is likely an entity.

6. What are Aggregates?

In Domain-Driven Design (DDD), an aggregate is a cluster of related objects that are treated as a single unit of consistency in a domain model. An aggregate is responsible for ensuring that the consistency and integrity of the objects it contains are maintained, and it is the only point of access to those objects from outside the aggregate.

An aggregate is typically composed of an aggregate root and its related objects. The aggregate root is the primary object in the aggregate and is responsible for maintaining the consistency of the aggregate. The related objects are objects that are closely associated with the aggregate root and are managed by it.

In a bounded context, the number of aggregates can vary depending on the complexity of the domain and the requirements of the system. There can be multiple aggregates in a bounded context, each responsible for a different set of related objects.

One way to determine the boundaries of aggregates is to use the concept of aggregate boundaries, which are the points in the domain where changes to the objects within an aggregate must be made together.

7. Do we really have to care about Aggregate in practice?

Yes. In programming, it is often useful to think about aggregates when designing the domain model, even though the focus is typically on entities and value objects. This is because aggregates help to define the boundaries of consistency and transactional scope within the domain.

In practical terms, when implementing a domain model in code, the aggregate is often the unit of work that is persisted to the database or other storage mechanism. This means that changes to the objects within an aggregate should be saved or discarded as a unit of work. In addition, all of the objects within an aggregate should be loaded together when retrieving data from the database.

It is important to carefully design the boundaries of aggregates to ensure that they are cohesive, maintainable, and consistent with the requirements of the domain.

8. The relationship between Features ⇌ Bounded contexts & Aggregates

Features are typically associated with bounded contexts, rather than aggregates. This is because bounded contexts define a specific area of the domain, and each bounded context has its own set of concepts, language, and rules.

Features within a bounded context are designed to support the requirements of that specific area of the domain. The key to designing features within a bounded context is to ensure that they are aligned with the needs of the domain and they are consistent with the language and concepts of the bounded context.

In some cases, a feature may require the coordination of multiple aggregates, each responsible for a different aspect of the feature. Alternatively, a feature may require the creation of a new aggregate to manage a specific aspect of the feature.


© 2016-2024  GinkCode.com