Mastering Domain‑Driven Design: From Data Models to Rich Domain Objects
This article explores practical Domain‑Driven Design in a B‑to‑B setting, comparing data‑centric and object‑centric modeling, illustrating blood‑loss, anemia, and rich models, and showing how dependency injection, testing strategies, repository abstractions, and deployment architectures can improve software quality and maintainability.
Preface
After many years of coding and discussing design with experts, the author reflects on the varied opinions about Domain‑Driven Design (DDD) and emphasizes that good design, regardless of the school of thought, is valuable.
Domain Model Exploration
Hema’s B‑to‑B business involves complex relationships that demand clear domain modeling to avoid technical debt. The team applied DDD throughout a system, adapting and improving the approach.
Domain Model Design: Object vs Database
Two modeling dimensions are considered: Data Modeling (database‑centric) and Object Modeling (object‑oriented). Most architects start with data modeling, but the starting point greatly influences the final system shape.
Data modeling creates a clear domain model that improves product structure, maintainability, and evolution; it is essentially a modern “data dictionary”.
Object Modeling
Object modeling abstracts system relationships through classes, offering encapsulation, inheritance, and polymorphism, which make domain models richer and more expressive than pure tables.
Reference: relational tables often require a third table for many‑to‑many relationships, which is hard for business users to understand.
Encapsulation: classes can contain behavior, not just data.
Inheritance & Polymorphism: classes can differentiate behavior (e.g., a person can run, a pig cannot).
Domain Model Types: Blood‑Loss, Anemia, Rich Models
Blood‑Loss Model : a database‑centric design where POJOs have only simple getters/setters and relationships are expressed via IDs handled by a manager.
Anemia Model : enriches objects with direct references (e.g., a Son object knows its Father), reducing the need for a manager to resolve IDs.
Rich (Charged) Model : domain objects contain persistence logic (e.g., a repository reference), which improves functionality but makes unit testing harder.
Dependency Injection in Domain Models
Using constructor injection makes objects test‑friendly and clearly indicates required dependencies. Singleton components managed by Spring can be injected, while objects created with new cannot receive annotation‑based injection.
Prefer constructor injection for better testability.
Testing‑Friendly Domain Models
Blood‑Loss and Anemia models are naturally test‑friendly because they are pure in‑memory objects. Rich models require mocking repositories to isolate tests.
Repository Implementation in Hema
Hema introduces a Tunnel interface that abstracts persistence. Domain objects are converted to POJOs and handed to the Tunnel, allowing different database implementations without coupling domain logic to storage.
Deployment Architecture
Hema’s architecture can be a single large domain model or split into bounded contexts. The article shows a diagram of a bounded‑context approach and a large‑domain deployment.
Conclusion
Hema’s adoption of DDD has improved system extensibility and stability. Ongoing explorations in distributed workflow engines and graphic rendering engines demonstrate a commitment to advancing architectural practices.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
