Domain-driven design
Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.[1] The premise of domain-driven design is the following:
- Placing the project's primary focus on the core domain and domain logic
- Basing complex designs on a model
- Initiating a creative collaboration between technical and domain experts to iteratively cut ever closer to the conceptual heart of the problem.
Domain-driven design is not a technology or a methodology. DDD provides a structure of practices and terminology for making design decisions that focus and accelerate software projects dealing with complicated domains.
The term was coined by Eric Evans in his book of the same title[2].
Contents |
[edit] Core definitions
- Domain A sphere of knowledge, influence, or activity. The subject area to which the user applies a program is the domain of the software.
- Model A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.
- Ubiquitous Language A language structured around the domain model and used by all team members to connect all the activities of the team with the software.
- Context The setting in which a word or statement appears that determines its meaning.
[edit] Prerequisites for the successful application of DDD
- Your domain is not trivial
- The project team has experience and interest in OOP/OOD
- You have access to domain experts
- You have an iterative process
[edit] Strategic domain-driven design
Ideally, we would prefer to have a single, unified model. While this is a noble goal, in reality it always fragments into multiple models. It is more useful to recognize this fact of life and work with it.
Strategic Design is a set of principles for maintaining model integrity, distillation of the Domain Model and working with multiple models.
The following image demonstrates the patterns in Strategic Domain-Driven Design and the relationships between them. 
[edit] Bounded context
Multiple models are in play on any large project. Yet when code based on distinct models is combined, software becomes buggy, unreliable, and difficult to understand. Communication among team members becomes confused. It is often unclear in what context a model should not be applied.
Therefore: Explicitly define the context within which a model applies. Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.
[edit] Continuous Integration
When a number of people are working in the same bounded context, there is a strong tendency for the model to fragment. The bigger the team, the bigger the problem, but as few as three or four people can encounter serious problems. Yet breaking down the system into ever-smaller contexts eventually loses a valuable level of integration and coherency.
Therefore: Institute a process of merging all code and other implementation artifacts frequently, with automated tests to flag fragmentation quickly. Relentlessly exercise the ubiquitous language to hammer out a shared view of the model as the concepts evolve in different people’s heads.
[edit] Context map
An individual bounded context leaves some problems in the absence of a global view. The context of other models may still be vague and in flux.
People on other teams won’t be very aware of the context bounds and will unknowingly make changes that blur the edges or complicate the interconnections. When connections must be made between different contexts, they tend to bleed into each other.
Therefore: Identify each model in play on the project and define its bounded context. This includes the implicit models of non- object-oriented subsystems. Name each bounded context, and make the names part of the ubiquitous language. Describe the points of contact between the models, outlining explicit translation for any communication and highlighting any sharing. Map the existing terrain. Take up transformations later.
[edit] Building Blocks of DDD
In the book Domain-Driven Design[2], a number of high-level concepts and practices are articulated, such as ubiquitous language meaning that the domain model should form a common language given by domain experts for describing system requirements, that works equally well for the business users or sponsors and for the software developers. The book is very focused at describing the domain layer that is one of the common layers in an object-oriented system with a multilayered architecture. In DDD, there are artifacts to express, create, and retrieve domain models:
- Entity: An object that is not defined by its attributes, but rather by a thread of continuity and its identity.
Example: Most airlines distinguish each seat uniquely on every flight. Each seat is an entity in this context. However, Southwest Airlines (or EasyJet/RyanAir for you Europeans...) does not distinguish between every seat; all seats are the same. In this context, a seat is actually a value object.
- Value Object: An object that contains attributes but has no conceptual identity. They should be treated as immutable.
Example: When people exchange dollar bills, they generally do not distinguish between each unique bill; they only are concerned about the face value of the dollar bill. In this context, dollar bills are value objects. However, the Federal Reserve may be concerned about each unique bill; in this context each bill would be an entity.
- Aggregate: A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregrate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
Example: When you drive a car, you do not have to worry about moving the wheels forward, making the engine combust with spark and fuel, etc.; you are simply driving the car. In this context, the car is an aggregate of several other objects and serves as the aggregate root to all of the other systems.
- Services: When an operation does not conceptually belong to any object. Following the natural contours of the problem, you can implement these operations in services. The Service concept is called "Pure Fabrication" in GRASP.
- Repositories: methods for retrieving domain objects should delegate to a specialized Repository object such that alternative storage implementations may be easily interchanged.
- Factories: methods for creating domain objects should delegate to a specialized Factory object such that alternative implementations may be easily interchanged.
[edit] Relationship to other ideas
- Object-oriented analysis and design
- Although in theory, the general idea of DDD need not be restricted to object-oriented approaches, in practice DDD seeks to exploit the powerful advantages that object-oriented techniques make possible.
- Model-driven engineering (MDE)
- Model-driven architecture (MDA)
- While DDD is compatible with MDA, the intent of the two concepts is somewhat different. MDA is concerned more with the means of translating a model into code for different technology platforms than with the practice of defining better domain models.
- POJOs and POCOs
- POJOs and POCOs are technical implementation concepts, specific to the Java and .NET framework respectively. However, the emergence of the terms POJO and POCO, reflect a growing view that, within the context of either of those technical platforms, domain objects should be defined purely to implement the business behaviour of the corresponding domain concept, rather than be defined by the requirements of a more specific technology framework.
- The naked objects pattern
- This pattern is based on the premise that if you have a good enough domain model, the user interface can simply be a reflection of this domain model; and that if you require the user interface to be direct reflection of the domain model then this will force the design of a better domain model.[3]
- Domain-specific programming language (DSL)
- DDD does not specifically require the use of a DSL, though it could be used to help define a DSL and support methods like domain-specific multimodeling.
- Aspect-oriented programming (AOP)
- AOP makes it easy to factor out technical concerns (such as security, transaction management, logging) from a domain model, and as such makes it easier to design and implement domain models that focus purely on the business logic.
- Command and Query Responsibility Segregation (CQRS): CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).
[edit] Software tools to support domain-driven design
Practicing DDD does not depend upon the use of any particular software tool or framework. Nonetheless, there is a growing number of open-source tools and frameworks that provide support to the specific patterns advocated in Evans' book or the general approach of DDD. Among these are:
- Actifsource is a plug-in for Eclipse which enables software development combining DDD with model-driven engineering and code generation.
- Castle Windsor/MicroKernel: an Inversion of Control/Dependency Injection container for the Microsoft.NET Framework to provide Services, Repositories and Factories to consumers.
- CodeFluent Entities: a model-driven software factory. It provides architects and developers a structured method and the corresponding tools to develop .NET applications, based on any type of architecture, from an ever changing business model and rules.
- DataObjects.Net: rapid database application development framework supporting object-relational mapping and DDD.
- Domdrides: A useful library for implementing DOMain-DRIven DESign in Java.
- ECO (Domain Driven Design): Framework with database, class, code and state machine generation from UML diagrams by CapableObjects.
- FLOW3: A PHP based application framework centered on DDD principles. Fosters clean Domain Models and supports the concept of Repository, Entity and Value Object. Also provides Dependency Injection and an AOP framework.
- Habanero.NET (Habanero) is an Open Source Enterprise Application framework for creating Enterprise applications using the principles of Domain-driven design and implemented in .NET.
- JavATE: a set of Java libraries that enables application development inspired by domain driven design.It gives you standard interfaces and implementations for the domain driven design building blocks so you can focus on your strategic design instead of reinventing the wheel of the building blocks each time.
- ManyDesigns Portofino is an open source, model-driven web-application framework for high productivity and maintainability. It provides CRUD forms, relationships, workflow management, dashboards, breadcrumbs, searches, single sign-on, permissions, and reporting.
- Naked Objects: implements the naked objects pattern; supports dependency injection; and provides re-usable implementations of the DDD concepts of Repository, Factory and Service.
- NReco: lightweight open-source domain-specific MDD framework for .NET. Integrated with JQuery, Open NIC.NET, OGNL, Log4Net, Lucene.NET, SemWeb etc.
- OpenMDX: Open source, Java based, MDA Framework supporting Java SE, Java EE, and .NET. OpenMDX differs from typical MDA frameworks in that "use models to directly drive the runtime behavior of operational systems".
- OpenXava: Generates an AJAX application from JPA entities. Only it's needed to write the domain classes to obtain a ready to use application.
- Roma Meta Framework: DDD centric framework. The innovative holistic approach lets the designer/developer to view anything as a POJO: GUI, I18N, Persistence, etc.
- Sculptor: a code-generation framework that uses DDD terminology.
- Sculpture - Model Your Life: Sculpture is one of the most powerful Open Source Model-driven development Generators. It can be used for everything from simple CRUD applications to complex enterprise applications - Sculpture comes with a list of ready-made Molds for common architectures like NHibernate, Entity Framework, WCF, CSLA, Silverlight, WPF, and ASP.NET MVC.
- Strandz: A DDD framework that provides implementation independence from both the UI layer and domain layer of the application. The programmer constructs a wire model of the application using special classes.
- TrueView for .NET: An easy-to-use framework that supports DDD and the naked objects pattern. Useful for teams starting out with DDD.
- Tynamo: Tynamo is open source, model-driven, full-stack web framework based on Tapestry 5, implemented in Java in the spirit of naked objects pattern
[edit] References
- ^ Definition on domaindrivendesign.org
- ^ a b Evans, E., Domain-Driven Design - Tackling Complexity in the Heart of Software, 2004, Addison-Wesley
- ^ Haywood, D., Domain-Driven Design using Naked Objects, 2009, Pragmatic Programmers
[edit] External links
- Eric Evans on Domain Driven Design - Putting the Model to Work
- Eric Evans on Domain Driven Design - Strategic Design
- Jimmy Nilsson on Domain Driven Design
- Domain-Driven Design forum (English)
- Article An Introduction to Domain Driven Design
- Qi4j a framework for domain centric application development, including evolved concepts from AOP, DI and DDD
- JdonFramework is a light-weight framework for developing Domain-Driven Design applications in the spirit of Evans
- Romaframework a Domain Driven Design approach <meta>framework
- Greg Young, CQRS, Task Based UIs, Event Sourcing agh!