Domain Driven Design - Architecture


Today we are going to discuss domain driven design (DDD) approach and why we need this and its usage, on top of that, why the current industry is focusing on this approach.

What is Domain Driven Design Approach?

Firstly this approach navigates from top to bottom scenarios such as the main focus for this approach relates to the business instead of the technology stack. The domain should be as it is currently what the customer use case scenario. Typically as a starter, we use technology first instead of business, and we call this as a tactical solution, which starts from the bottom to the top approach, however, in this case, it is vice versa. 

The focus of this approach is to understand the business use case and then drill down to the granular layer. Consider a large system such as ERP, it has huge domains and subdomains such as Manufacturing, Supply chain, HRMS as domain and Payroll, Leave Management, LMS, and talent management are subdomains of HRMS and etc.,

Types of Designing Software 

  • Tactical Design Approach
    • This approach won't sustain for the long run, and the operation cost will increase in a steady run. 
    • Repetitive work
    • The system fails when the business expands its module.
  • Strategic Design Approach
    • The strategic approach is one which focuses on the business and targets for the longer run to sustain, and it gives agility to adapt to any kind of scenario and use cases. Basically, what I mean to say here is, in this approach, we create a base that is flexible for future extension. 
    • Typically in this approach, firstly, we bring a conceptual design that adheres to the business case study.
    • This approach typically guides us on how to decouple the domain layer from another layer (s).

Architecture Glance 

Key points while designing domain Model 

  • Understand the Domain: Gain a deep understanding of the problem domain, its concepts, and its relationships. This involves conducting thorough research, analyzing requirements, and consulting with domain experts.

  • Identify Key Concepts: Identify the essential concepts and entities within the domain. These can be tangible objects, abstract ideas, or processes that are central to the problem being solved. Create classes or entities to represent these concepts in the model.

  • Define Relationships: Determine the relationships between the identified concepts. Relationships can be associations, aggregations, compositions, or inheritances. Clearly define the multiplicity, cardinality, and roles of each relationship.

  • Encapsulate Behavior: Define the behaviour or operations associated with each concept. These operations represent the actions that can be performed on the objects or entities in the model. Consider both the state-changing methods (mutators) and the query methods (accessors) associated with each concept.

  • Capture Constraints: Identify and capture the constraints or rules that govern the domain. These constraints can include business rules, validation rules, and invariants that must be satisfied by the objects or entities in the model.

  • Model Persistence: Consider how the domain model will be persisted or stored in a database or other storage mechanism. Design the necessary data access and persistence mechanisms, such as repositories or data mappers, to handle the interaction between the domain model and the data storage layer.

  • Keep it Simple: Strive for simplicity and clarity in the domain model. Avoid unnecessary complexity and keep the model focused on the core problem domain. Use appropriate modelling techniques, such as abstraction, encapsulation, and modularization, to make the model more manageable and maintainable.

  • Iterative Refinement: Recognize that designing a domain model is an iterative process. Refine and evolve the model over time-based on feedback, changing requirements, and a deeper understanding of the domain. Regularly review and update the model to ensure it accurately represents the problem domain.

  • Maintain Separation of Concerns: Separate the domain model from other layers of the system, such as the user interface or infrastructure. Follow the principles of domain-driven design (DDD) to ensure a clear separation of concerns and to keep the domain model focused on the core business logic.

  • Testability: Design the domain model in a way that allows for effective testing. Use appropriate testing techniques, such as unit testing and integration testing, to validate the behaviour and correctness of the model. Consider using techniques like dependency injection to facilitate testability.

Concepts of Domain-Driven Design

Name Brief Description Example
Ubiquitous Language It emphasizes the use of a common, shared language between domain experts and developers. This language, known as the "ubiquitous language," should be used in all aspects of the software development process, including code, documentation, and conversations. It helps to bridge the gap between domain experts and developers, ensuring a clear and consistent understanding of the problem domain. While exposing an API, the action should be a proper business use case. For eg.,
  • GetEmployeeByEmployeeId(int) instead of GetEmpData(int)
  • Create a class name and object to adhere to the business, here meant to say tech stack or coding should align.
Bounded Context A bounded context represents a specific area or subsystem within the overall system where a particular domain model and ubiquitous language apply. It defines the boundaries within which the models, concepts, and language are consistent and meaningful. Bounded contexts help manage the complexity of large domains by breaking them down into smaller, more manageable parts. Setting the boundary for the domain model. For eg., It only does its job not everything else. 
Aggregates Aggregates are clusters of closely related objects that are treated as a single unit. They are responsible for enforcing consistency and invariants within the domain. An aggregate has a root entity, known as the aggregate root, which acts as the entry point for accessing and modifying the objects within the aggregate. Aggregates help maintain transactional consistency and encapsulate complex business logic It's a kind of orchestra, which connect all the required object to run your business. 
Entities Entities are objects that have a unique identity and are defined by their attributes and behaviour. They represent concepts with continuity over time and are typically mutable. Entities encapsulate the core business logic and behaviour of the domain. Entities could be customers, orders, or products
Value Objects Value objects are objects that do not have a unique identity but are defined by their attributes. They represent concepts based solely on their attribute values and are immutable. They help enforce semantic integrity and provide meaningful abstractions. Value objects could be dates, addresses, or monetary values.
Domain Services Domain services encapsulate operations or behaviours that do not naturally fit within a specific entity or value object. They typically represent domain operations that require the collaboration of multiple objects or involve external dependencies. Domain services can be stateless or stateful and play a crucial role in implementing complex business processes. LMS service will do all kinds of learning and the payroll service will take care of only salary dispatch.
Domain Events Domain events represent significant occurrences or changes within the domain. They capture and communicate meaningful business activities or state transitions. Domain events are used to maintain loose coupling and enable different parts of the system to react to changes asynchronously. They can be published and subscribed to by interested components within the system. Once the order is placed in the e-commerce platform, the ordering service will pick the events from the queue it will proceed further. Once it's done it will set it back to the queue which is taken care of by the rest of the service accordingly.  
  • Ordering => Queue => Payment
  • Payment done => Queue => Inventory
  • Inventory done=> Queue => Shippment
Repositories Repositories provide a bridge between the domain model and the data persistence layer. They encapsulate the logic for retrieving and storing aggregates from/to the underlying data store. Repositories abstract away the details of data access, allowing the domain model to remain focused on business logic without being tightly coupled to specific persistence mechanisms. This act as a connector to get the data from infrastructure layer. 

Similar Articles