16 Nov 2023
Let's take an example of strategic design in DDD for an ERP system, focusing on the Order Management domain within the larger ERP context.
Context:
Imagine a company that manufactures and sells electronic devices. The company has various business units, including manufacturing, sales, inventory management, and customer relations. The goal is to design a comprehensive ERP system to streamline the order management process.
Strategic Design Steps:
-
Identify Bounded Contexts:
- Sales Context:
- Subdomains: Order, Customer, Product, Pricing
- Manufacturing Context:
- Subdomains: Production, Inventory
- Sales Context:
-
Define Core Domains:
- Order Management Domain:
- Entities: Order, Order Line, Customer, Product
- Value Objects: Address, Order Status
- Aggregates: Order Aggregate (consisting of Order and Order Line)
- Order Management Domain:
-
Strategic Domain Events:
- Order Placed: Triggered when a new order is placed.
- Order Shipped: Triggered when an order is shipped from the warehouse.
-
Context Mapping:
- Establish clear communication channels and integration points between the Sales and Manufacturing contexts.
- Define shared Kernel to ensure consistency in shared concepts like Product and Customer.
-
Define Anti-Corruption Layer (ACL):
- Implement an ACL to translate messages between the Sales and Manufacturing contexts, ensuring that the models from one context don't corrupt the models in the other.
-
Aggregate Root Design:
- Order Aggregate:
- Ensures consistency and encapsulation of order-related business rules.
- Manages the order lifecycle, including order placement, modification, and shipment.
- Order Aggregate:
-
Strategic Repositories:
- Implement repositories for key aggregates (e.g., OrderRepository) to manage the persistence of aggregates.
-
Value Objects for Immutability:
- Use value objects for immutability, such as an Address value object for customer shipping information.
-
Policy Design:
- Define pricing and discount policies as domain services to calculate the total order price based on the products and any applied discounts.
-
Continuous Refinement:
- Regularly review and refine the strategic design based on evolving business requirements and feedback from stakeholders.
Below is a simplified Java pseudo-code representation of the strategic design steps outlined above for an ERP system, focusing on Order Management within the DDD context.
Step 1: Identify Bounded Contexts
// Sales Context
public class Order { /* ... */ }
public class Customer { /* ... */ }
public class Product { /* ... */ }
public class Pricing { /* ... */ }
// Manufacturing Context
public class Production { /* ... */ }
public class Inventory { /* ... */ }
Step 2: Define Core Domains
// Order Management Domain
public class Order {
private OrderId orderId;
private List<OrderLine> orderLines;
private Customer customer;
private OrderStatus status;
// ... other attributes and methods
}
public class OrderLine {
private Product product;
private int quantity;
private Money price;
// ... other attributes and methods
}
public class Customer { /* ... */ }
public class Product { /* ... */ }
// Enums
public enum OrderStatus { PENDING, SHIPPED }
Step 3: Strategic Domain Events
// Events
public class OrderPlacedEvent { /* ... */ }
public class OrderShippedEvent { /* ... */ }
Step 4: Context Mapping
// Context Mapping
// Implement communication channels and integration points between Sales and Manufacturing contexts
Step 5: Define Anti-Corruption Layer (ACL)
// Anti-Corruption Layer
public class SalesToManufacturingTranslator {
public ManufacturingOrder translate(Order order) {
// Translate Order to ManufacturingOrder
}
}
public class ManufacturingToSalesTranslator {
public Order translate(ManufacturingOrder manufacturingOrder) {
// Translate ManufacturingOrder to Order
}
}
Step 6: Aggregate Root Design
// Aggregate Root
public class OrderAggregate {
private Order order;
// ... other attributes and methods
public void placeOrder(OrderPlacedEvent event) {
// Handle order placement logic
}
public void shipOrder(OrderShippedEvent event) {
// Handle order shipment logic
}
}
Step 7: Strategic Repositories
// Repository
public interface OrderRepository {
Order getById(OrderId orderId);
void save(Order order);
}
Step 8: Value Objects for Immutability
// Value Object
public class Address {
private String street;
private String city;
private String zipCode;
// ... other attributes and methods
}
Step 9: Policy Design
// Domain Service
public class PricingService {
public Money calculateTotalPrice(Order order) {
// Calculate total price based on order and pricing policies
}
}
Step 10: Continuous Refinement
// Regularly review and refine the design based on evolving requirements
Please note that this pseudo-code is simplified for illustration purposes. In a real-world scenario, you would need to implement the methods, handle exceptions, and consider additional aspects like persistence, validation, and error handling.