09 Nov 2023



Intermediate

Let's explore the fundamental principles of Domain-Driven Design:

  1. Ubiquitous Language: refers to the practice of using a common and shared language throughout the entire software development process in Domain-Driven Design (DDD). This language is used by both technical and non-technical team members to ensure a clear and consistent understanding of the domain and its complexities. By maintaining a ubiquitous language, everyone involved in the project can communicate more effectively, leading to better collaboration, reduced misunderstandings, and a more successful software development process.

    Here are some examples of Ubiquitous Language in DDD:

    • Customer: In ubiquitous language, everyone, from developers to business analysts, refers to individuals purchasing goods as "customers." This term is used consistently across code, documentation, and discussions.

    • Shopping Cart: When discussing the process of adding items to be purchased, the term "shopping cart" is universally understood and used. It's the common language for describing this specific aspect of the e-commerce domain.

    • Checkout: The process of completing a purchase is referred to as "checkout" by everyone involved. Whether you're talking about it in a meeting or implementing the feature in code, the term remains consistent.

    • Inventory: When dealing with product availability, the term "inventory" is used across the board. This ensures that everyone, regardless of their role, understands the concept and its implications.

    By maintaining this ubiquitous language, a developer discussing a feature with a business analyst or a project manager can use the same terminology, fostering clear communication and a shared understanding of the domain.

  2. Bounded Contexts: Bounded Context is like a mini-domain within a larger domain. It has its own unique rules, vocabulary, and team of experts. This helps to break down a large and complex domain into more manageable pieces, making it easier to understand and develop software for.

Bounded Contexts in Domain-Driven Design (DDD) are a way to organize the domain model of a complex system into smaller, more manageable pieces. Each bounded context has its own ubiquitous language, which is a shared understanding of the domain model among all stakeholders.

Example: Imagine an e-commerce website

Imagine an e-commerce website, where the domain encompasses product management, order processing, and Customer management. Each of these areas represents a distinct bounded context with its own specialized vocabulary and business rules. For instance, the product management context focuses on product descriptions, specifications, and pricing, while the order processing context deals with inventory management, shipping logistics, and payment gateways.

  1. Order Management Bounded Context:

    • Description: Deals with placing, managing, and fulfilling orders, including customer information, order items, and shipping details.
    • Entities and Concepts:
      • Order: Represents a customer's purchase with details like products, quantities, and shipping information.
      • Customer Information: Stores details about the customer placing the order.
      • Shipping Details: Manages information related to the delivery of orders.
    • Ubiquitous Language: Terms like "Order," "Customer Information," and "Shipping Details" are specific to this context.
  2. Product Management Bounded Context:

    • Description: Focuses on managing product catalogs, attributes, pricing, and inventory levels.
    • Entities and Concepts:
      • Product: Represents items available for purchase with details like descriptions, specifications, and pricing.
      • Inventory: Tracks product availability and manages stock levels.
      • Pricing: Manages the pricing information for products.
    • Ubiquitous Language: Terms like "Product," "Inventory," and "Pricing" are specific to this context.
  3. Customer Engagement Bounded Context:

    • Description: Handles customer interactions, including support tickets, marketing campaigns, and loyalty programs.
    • Entities and Concepts:
      • Support Ticket: Represents customer inquiries or issues that need resolution.
      • Marketing Campaign: Manages promotional efforts to attract and retain customers.
      • Loyalty Program: Tracks and rewards customer loyalty.
    • Ubiquitous Language: Terms like "Support Ticket," "Marketing Campaign," and "Loyalty Program" are specific to this context.
  4. Domain Model: A domain model is a conceptual model of a business domain that captures the key concepts, relationships, and behaviors of that domain. It is created by working with domain experts and software developers to create a shared understanding of the domain. The domain model is then used to guide the design and implementation of software systems that accurately reflect the real world.

    The domain model is the blueprint for the software that solves the problem. It's a visual representation of the key concepts, rules, and relationships in your problem domain. Imagine it as a map of the important concepts and relationships in a business problem, created by business experts and software developers together. It helps to guide the design of a software system that solves the problem in a way that is understandable and efficient.

    Here are some real-world examples of domain models in DDD:

    • E-commerce website: The domain model for an e-commerce website might include entities such as products, customers, orders, and payments. The relationships between these entities would be modeled to capture the business rules of the website, such as how products are associated with customers, how orders are placed and fulfilled, and how payments are processed.

      • Entities:
        • Products
        • Customers
        • Orders
        • Payments
      • Relationships:
        • Products and Customers: Customers can view and purchase products.
        • Orders and Customers: Customers place orders.
        • Payments and Orders: Payments are linked to specific orders.
      • Business Rules:
        • Customers can browse and buy multiple products.
        • An order is created when a customer purchases one or more products.
        • Payments are processed for completed orders.
    • Social media platform: The domain model for a social media platform might include entities such as users, posts, comments, and likes. The relationships between these entities would be modeled to capture the business rules of the social media platform, such as how users can post content, how other users can interact with that content, and how users can connect with each other.

      • Entities:
        • Users
        • Posts
        • Comments
        • Likes
      • Relationships:
        • Users and Posts: Users create and share posts.
        • Users and Comments: Users can comment on posts.
        • Users and Likes: Users can like posts.
      • Business Rules:
        • Users can create, share, and interact with posts.
        • Users can comment on and like posts.
  5. Entities and Value Objects:

    • Entities: In DDD, an entity is an object that represents a real-world thing. Entities are objects that have a unique identity and can change over time. Entities are typically persisted in a database, but they can also be stored in memory or other data stores.

      Example: A customer, an order, or a product are all entities.

    • Value objects: Value objects are typically immutable objects(meaning that they cannot be changed once they are created). They do not have a unique identity. Value objects are often used to model quantities, dimensions, and other characteristics of entities.

      Example: A customer's name, address, or phone number are all value objects.

  6. Aggregates: In Domain-Driven Design (DDD), an aggregate is a group of closely related domain objects treated as a singular unit. These aggregates comprise both entities and value objects, seen as a tightly connected whole.

    Here are some simple examples of aggregates:

    • An order aggregate might include the order itself, as well as the order items, shipping address, and billing address.

    • A product aggregate might include the product itself, as well as its price, inventory level, and any other related data.

    • A customer aggregate might include the customer's name, address, contact information, and order history.

  7. Repositories:A repository is a design pattern used to abstract the persistence and retrieval of domain objects, ensuring separation between the domain logic and the data storage. Repositories provide interfaces for storing, retrieving, and querying entities and aggregates within a domain.

    Repositorys serve as a bridge between the application layer (where business logic resides) and the persistence layer (where data is stored).They typically offer abstraction methods for basic CRUD operations (create, read, update, delete) on domain objects. Moreover, they facilitate querying and provide methods for searching, filtering, and managing the storage and retrieval of these entities from a database or any underlying data source.

    Here are some real-world examples of repositories in DDD:

    • E-commerce:

      • ProductRepository: This repository would be responsible for storing and retrieving product data, such as product name, description, price, and inventory levels.

      • OrderRepository: This repository would be responsible for storing and retrieving order data, such as customer information, shipping information, and order items.

    • Healthcare:

      • PatientRepository: This repository would be responsible for storing and retrieving patient data, such as patient name, address, date of birth, and medical history.

      • AppointmentRepository: This repository would be responsible for storing and retrieving appointment data, such as appointment date, time, and location.

  8. Services: Services are reusable classes that encapsulate business logic and operations. They are responsible for performing complex operations, such as business rules validation, calculations, orchestration etc..

    Here are some real-world examples of services in DDD:

    E-commerce

    • Order service: Responsible for managing the lifecycle of orders, from placement to fulfillment.
    • Payment service: Responsible for processing payments and managing customer accounts.
    • Product catalog service: Responsible for managing the product catalog, including product information, pricing, and inventory.
    • Recommendation service: Responsible for recommending products to customers based on their purchase history and other factors.

    Banking

    • Account service: Responsible for managing customer accounts, including deposits, withdrawals, and transfers.
    • Loan service: Responsible for processing loan applications and managing loan accounts.
    • Fraud detection service: Responsible for detecting and preventing fraudulent transactions.
    • Customer support service: Responsible for handling customer inquiries and resolving issues.

    Healthcare

    • Patient service: Responsible for managing patient records and appointments.
    • Billing service: Responsible for processing patient bills and managing insurance claims.
    • Medication management service: Responsible for managing patient prescriptions and refills.
    • Clinical decision support service: Responsible for providing clinicians with real-time information and recommendations to help them make better decisions about patient care.

    Other examples

    • Shipping service: Responsible for generating shipping labels and tracking shipments.
    • Notification service: Responsible for sending notifications to users, such as email alerts and push notifications.
    • Search service: Responsible for indexing and searching for content.
    • Analytics service: Responsible for collecting and analyzing data to generate reports and insights.
  9. Domain Events: Domain events in Domain-Driven Design (DDD) are records of things that have already happened in the domain. They are used to notify the state changes that have happened in the domain.

    Here are some examples of domain events:

    • OrderPlaced
    • ProductAddedToCart
    • PaymentProcessed
    • UserRegistered
    • CustomerSignedUpForNewsletter
  10. Factories: A factory is a class that is responsible for creating new domain objects. They encapsulate the complex rules and logic that is involved in creating new objects, and they provide a consistent interface for doing so.

    Here are some real-world examples of factories in DDD:

    • A car factory that creates new cars of different types, such as sedans, SUVs, and trucks.
    • A bank account factory that creates new bank accounts of different types, such as checking accounts, savings accounts, and money market accounts.
    • A user profile factory that creates new user profiles for a social media platform.
    • A product factory that creates new product listings for an e-commerce website.
    • A order factory that creates new orders for a retail business.
  11. Anti-Corruption Layer (ACL) in Domain-Driven Design (DDD) is a layer of abstraction that sits between the domain model and external systems. It is responsible for translating between the domain model and the foreign data models and APIs of those external systems. The goal of the ACL is to protect the domain model from being corrupted by the foreign concepts and models of the external systems.

    ACLs are typically used in cases where a domain needs to interact with an external system that is outside of its control, such as a legacy system, a third-party API, or a database. By using an ACL, the domain model can be isolated from these external systems, making it more resilient to change and easier to maintain.

    Here are some specific examples:

    • Online banking application: The anti-corruption layer could be used to translate between the bank's internal data model and the external data models of the various third-party services that the bank integrates with, such as credit scoring services, fraud detection services, and payment processing services.
    • E-commerce platform: The anti-corruption layer could be used to translate between the platform's internal data model and the data models of the various third-party services that the platform integrates with, such as shipping carriers, payment processors, and product catalogs.
    • Enterprise resource planning (ERP) system: The anti-corruption layer could be used to translate between the ERP system's internal data model and the data models of the various other systems that the ERP system integrates with, such as customer relationship management (CRM) systems, manufacturing execution systems (MES), and supply chain management (SCM) systems.
  12. Shared Kernel: A Shared Kernel in Domain-Driven Design (DDD) is a set of domain concepts and code that is shared by multiple bounded contexts. A bounded context is a conceptual boundary within a software system that separates different aspects of the domain. By sharing a kernel, bounded contexts can use the same domain concepts and code, which helps to ensure consistency and avoid duplication. Shared kernels can be implemented in a variety of ways.

    One common approach is to create a separate library project that contains the shared code. The bounded contexts can then reference this library project.

    Here is a simple analogy:

    Imagine a software system that has two bounded contexts: one for managing products and one for managing orders. Both of these bounded contexts need to represent the concept of a customer. Instead of defining a separate customer class in each bounded context, the two bounded contexts can share a single customer class from a shared kernel.

    Here are some real-world examples of the Shared Kernel pattern in Domain-Driven Design (DDD):

    • E-commerce: The Order Management and Payment Processing bounded contexts in an e-commerce system might share a common kernel that includes the following entities: Customer, Order, and OrderItem. This kernel would define the core concepts that are shared between the two contexts, such as the customer's information, the order details, and the line items in the order.
    • Healthcare: The Patient Records and Billing bounded contexts in a healthcare system might share a common kernel that includes the following entities: Patient, Appointment, and InsuranceClaim. This kernel would define the core concepts that are shared between the two contexts, such as the patient's demographic information, their appointments, and their insurance claims.
    • Banking: The Account Management and Transaction Processing bounded contexts in a banking system might share a common kernel that includes the following entities: Account, Customer, and Transaction. This kernel would define the core concepts that are shared between the two contexts, such as the customer's account information, their transactions, and the rules for managing accounts and processing transactions.
  13. Strategic Design: Strategic design in DDD is the process of defining the high-level architecture of a software system, including the identification of bounded contexts, the ubiquitous language, and the context maps. It is a collaborative process between domain experts and technical experts, and it is essential for ensuring that the system is aligned with the business needs and that it is maintainable and scalable.

    Here is a simple analogy to help understand strategic design in DDD:

    Imagine you are building a house. The first step is to develop a blueprint. The blueprint provides a high-level overview of the house, including its overall layout and the different rooms. It also shows how the different rooms are connected to each other.

    Strategic design in DDD is analogous to developing a blueprint for the software system. It provides a high-level overview of the business domain and the different bounded contexts. It also shows how the different bounded contexts are integrated with each other.

  14. Continuous Refinement: Continuous refinement in DDD is the ongoing process of improving the domain model over time. This is done by iteratively making adjustments and adaptations based on feedback from domain experts and stakeholders. This ensures that the software system remains aligned with the changing needs of the business.

    Example:

    Let's say we are developing a software system for a bank. One of the key concepts in the domain is the concept of an account. The account model might initially be very simple, with only a few basic attributes, such as account number, account type, and balance. However, as we learn more about the banking domain and the specific needs of our users, we may need to refine the account model to include additional attributes, such as account holder information, transaction history, and interest rates.

    By continuously refining the domain model, we can ensure that our software system remains accurate, flexible, and adaptable to change.

  15. Context Mapping: Context mapping is a technique used in Domain-Driven Design (DDD) to visualize and understand the relationships between different bounded contexts in a software system.A bounded context is a conceptual boundary within a software system that separates different parts of the system with different concerns. Context maps can be used to identify how different bounded contexts interact with each other, and to determine the best way to integrate them.

    Context maps are typically created using a whiteboard or other visual surface. The bounded contexts are drawn as rectangles, and the relationships between them are drawn as arrows. The arrows can be labeled to indicate the type of relationship, such as "produces data for" or "consumes data from."

Context Mapping in a diagram using ASCII characters.

    +---------------------+     +-----------------------+
    |  Sales Context     |     | Inventory Context    |
    |---------------------|     |-----------------------|
    | Customer            |     | Product               |
    | Order               |     | Stock                 |
    +---------------------+     +-----------------------+
              |                       |        |      
              v                       |        v
    +---------------------+           |  +-----------------------+
    | Shared Kernel      |            |  | Customer/Supplier     |
    |---------------------|           |  |-----------------------|
    | Customer (Sales)  |             |  | Sales depends on      |
    | Product (Inventory)|            |  | Product for fulfillment|
    +---------------------+           |  +-----------------------+
              |                       |
              |                       |  +-----------------------+
              |                       |  | Conformist            |
              |                       |  |-----------------------|
              +------------------------> Stock (Inventory)     |
              |                       |  | aligns representation |
              |                       |  | with Order (Sales)   |
              |                       |  +-----------------------+
              |                       |
              |                       |  +-----------------------+
              |                       |  | Anticorruption Layer |
              |                       |  |-----------------------|
              +------------------------> Translation layer     |
              |                       |  | between Sales and     |
              |                       |  | Inventory            |
              |                       |  +-----------------------+
              |                       |
              |                       |  +-----------------------+
              |                       |  | Open Host Service    |
              |                       |  |-----------------------|
              +------------------------> Exposes part of       |
					| Inventory for Sales   |
                                         +-----------------------+

Diagram represents the context mapping in Domain-Driven Design (DDD) with relationships between two bounded contexts: Sales and Inventory.

  • Bounded Contexts:

    • Sales Context: Contains entities like Customer and Order related to sales operations.
    • Inventory Context: Contains entities like Product and Stock related to inventory management.
  • Shared Kernel:

    • Elements like Customer in Sales and Product in Inventory share a subset of attributes or components.
  • Customer/Supplier:

    • The Sales context depends on the Inventory context for product-related information to fulfill orders.
  • Conformist:

    • Stock in the Inventory context aligns its representation with the Order in the Sales context to maintain consistency and compatibility.
  • Anticorruption Layer:

    • There's a translation layer between Sales and Inventory to maintain domain integrity. This layer ensures that each context understands the other's language without corrupting its own domain logic.
  • Open Host Service:

    • Part of the Inventory context is exposed to the Sales context, allowing Sales to utilize certain elements of the Inventory context without tightly coupling the two contexts.