Domain Driven Design and Development In Practice 1 An ...vb-net.com/ProgramTheory/Books/Domain...
Transcript of Domain Driven Design and Development In Practice 1 An ...vb-net.com/ProgramTheory/Books/Domain...
Domain Driven Design and Development In Practice 1
An Introduction To Domain-Driven Design 33
About InfoQ Our Audience Contribute About C4Media Exclusive updates on:
Facilitating the spread of knowledge and innovation in professional software development
| | | |1,296,180 Aug unique visitors
San Francisco Nov 7-11
London Mar 6-10, 2017
New YorkJun 26-30, 2017
Streaming Machine Learning Reactive Microservices Containers .NET All topics The InfoQ Podcast
You are here: InfoQ Homepage Articles Domain Driven Design and Development In Practice
Search
En 中文 日本 Fr Br
Domain Driven Design and Development In Practice
Posted by Srini Penchikala on Jun 12, 2008 | Discuss
Start your FREE TRIAL of AppDynamics Pro
The Ultimate DevOps Toolkit
An Enterprise Architect's Guide to APIIntegration for ESB and SOA
Powerful Continuous Integration Out of theBox - Try the Fully-Featured Version ofTeamCity
Download the FOREVER FREE and fully-featured version of TeamCity
Related Vendor Content
Related Sponsor
Background
Domain Driven Design (DDD) is about mapping business domain concepts into software artifacts.
Most of the writings and articles on this topic have been based on Eric Evans' book "Domain
Driven Design", covering the domain modeling and design aspects mainly from a conceptual and
design stand-point. These writings discuss the main elements of DDD such as Entity, Value
Object, Service etc or they talk about concepts like Ubiquitous Language, Bounded Context and
Anti-Corruption Layer.
The objective of this article is to cover the domain modeling and design from a practical stand-
point on how one would go about taking a domain model and actually implementing it. We will
look at the guidelines, best practices, frameworks and tools that the technical leads and
architects can use in the implementation effort. Domain Driven Design and Development is also
influenced by several architectural, design, and implementation aspects such as:
Business Rules
Persistence
Caching
Transaction Management
Security
Code Generation
Test Driven Development
Refactoring
This article talks about how these different factors affect the implementation project throughout
its lifecycle and what the architects should look for in realizing a successful DDD implementation.
I will start off with a list of characteristics a typical domain model should have, and when to use a
domain model in an enterprise (versus not using a domain model at all or using an anemic
domain model).
The article includes a sample loan
processing application to demonstrate how
design aspects and development best
practices discussed here, can be used in a
real-world domain driven development
project. The sample application uses
frameworks like Spring, Dozer, Spring
Security, JAXB, Arid POJOs and Spring
Dynamic Modules in implementing the loan
processing domain model. The example
code will be in Java, but it should be fairly
easy to understand for most developers,
regardless of language background.
Introduction
53
Share | Read laterMy Reading List
RELATED CONTENT
Software Developers Use Domain DrivenDesign to Drive Business Aug 17, 2016
12 Factor, or Cloud Native Apps -What Exactly Does that Mean forSpring Developers? Aug 31, 2016
SpringOne Platform 2016 TechnicalKeynote - 1 Aug 28, 2016
SpringOne Platform 2016 TechnicalKeynote - 4 Aug 26, 2016
Working with Multiple Databases inSpring Jul 30, 2016
Configure Once, Run Everywhere:Decoupling Configuration andRuntime Jun 17, 2016
Modular Java Applications with OSGi May 12, 2016
You, Me and Jigsaw Apr 02, 2016
Spring Framework 5 - Preview &Roadmap Mar 31, 2016
#NoXML: Eliminating XML in YourSpring Projects Mar 11, 2016
Developing Cloud-native Applicationswith Eclipse and the Spring ToolSuite Apr 11, 2016
Development Architecture& Design
Data Science Culture &Methods
DevOps
Login
Page 1 of 32 Assembled by RunPDF.com
How to Build (and Scale) withMicroservices
A domain model offers several benefits
some of which are:
It helps the team create a common
model, between the business and IT
stakeholders in the company, that the team can use to communicate about the business
requirements, data entities, and process models.
The model is modular, extensible and easy to maintain as the design reflects the business
model.
It improves the reusability and testability of the business domain objects.
On the flip side, let's see what happens when IT teams don't follow a domain model approach for
developing medium to large size enterprise software applications.
Not investing in a domain model and development effort leads to an application architecture with
a "Fat Service Layer" and an "Anemic Domain Model" where facade classes (usually Stateless
Session Beans) start accumulating more and more business logic and domain objects become
mere data carriers with getters and setters. This approach also leads to domain specific
business logic and rules being scattered (and duplicated in some cases) in several different
facade classes.
Anemic domain models, in most cases, are not cost-effective; they don't give the company a
competitive advantage over other companies because implementing business requirement
changes in this architecture take too long to develop and deploy to production environment.
Before we look at different architectural and design considerations in a DDD implementation
project, let's take a look at the characteristics of a rich domain model.
The domain model should focus on a specific business operational domain. It should align
with the business model, strategies and business processes.
It should be isolated from other domains in the business as well as other layers in the
application architecture.
It should be reusable to avoid any duplicate models and implementations of the same core
business domain elements.
The model should be designed loosely coupled with other layers in the application, meaning
no dependencies on the layers on either side of domain layer (i.e. database and facade
layers).
It should be an abstract and cleanly separated layer enabling easier maintenance, testing,
and versioning. The domain classes should be unit testable outside the container (and from
inside the IDE).
It should be designed using a POJO programming model without any technology or
framework dependencies (I always tell the project teams I work with in my company, that the
technology we use for software development is Java).
The domain model should be independent of persistence implementation details (although
the technology does place some constraints on the model).
It should have minimum dependencies on any infrastructure frameworks because it will
outlive these frameworks and we don't want any tight coupling on any external framework.
In order to achieve a better Return On Investment (ROI) on software development efforts, the
senior management in Business Units and IT has to commit to the investment (of time, money,
and resources) in business domain modeling and its implementation. Let's look at some of the
other factors that are required for implementing a domain model.
The team should have regular access to business domain subject matter experts.
IT team (modelers, architects, and developers) should possess good modeling and design
skills.
Analysts should have good business process modeling skills.
Architects and developers should have strong Object Oriented Design (OOD) and
Programming (OOP) experience.
Role of Domain Driven Design in Enterprise Architecture
Domain modeling and DDD play a vital role in Enterprise Architecture (EA). Since one of the
goals of EA is to align IT with the business units, the domain model which is the representation of
business entities, becomes a core part of EA. This is why most of the EA components (business
or infrastructural) should be designed and implemented around the domain model.
Domain Driven Design and SOA
Service Oriented Architecture (SOA) is gaining more and more momentum in the recent past to
Sponsored by
SPONSORED CONTENT
The Ultimate DevOps ToolkitThis e-book breaks down the
various foundational components
that build up the transition to
DevOps within an enterprise. It
also introduces the continuous life
cycle that maintains the
integration and collaboration
needed to deliver an exceptional
end user experience with your
applications.
Node.js Performance CheatSheetManaging Node.js applications
has become increasingly difficult
as the environments are more
complex than ever. In this cheat
sheet, you'll find actionable tips to
help you effectively monitor and
manage your complex Node.js
environment.
RELATED CONTENT
Invokedynamic - Java’s SecretWeapon Mar 22, 2016
Stormpath's Java SDK 1.0 Released Aug 31, 2016
Dropwizard Java REST Framework Version1.0.0 Features Updated Library Support,Scala, and Java 8 Aug 30, 2016
Solving Fat JAR Woes at HubSpot Aug 22, 2016
LinkedIn Test Butler Aims to Improve UI Testingon Android Aug 19, 2016
API Mocking Tool WireMock v2 Released withImproved Request Matching and StubManagement Aug 16, 2016
The New Scala Center Focuses on Educationand the Scala Community Aug 16, 2016
Oracle Unveils Plan to Revamp Java EE 8 forthe Cloud Aug 15, 2016
Survey: Android’s Lead is Consolidated Aug 10, 2016
Using Templates to Transform WebService Results into Markup Aug 31, 2016
Page 2 of 32 Assembled by RunPDF.com
help the teams build software components and services based on the business processes and to
speed up the time to market for the new products. Domain driven design is a key element of SOA
architecture because it helps in encapsulating the business logic and rules in domain objects.
The domain model also provides the language and context with which the service contract can
be defined.
An SOA effort should include the design and implementation of the domain model if one doesn't
already exist. If we put too much emphasis on the SOA services and ignore the importance of
domain model, we will end up with an anemic domain model and bloated services in the
application architecture.
An ideal scenario is the one where DDD effort is implemented iteratively with developing the
application layer and SOA components at the same time as these are the direct consumers of
domain model elements. With a rich domain implementation, SOA design will become relatively
simple by providing a shell (proxy) to the domain objects. But if we focus too much on the SOA
layer without a decent domain model in the back-end, the business services will be calling an
incomplete domain model, which can result in a brittle SOA architecture.
Project Management
A domain modeling project typically includes the following steps:
Model and document business processes first.
Select a candidate business process and work with the business domain experts to
document it using the Ubiquitous Language.
Identify all the services that are required for the candidate business process. These services
can be atomic (single step) or orchestrated (multi-step with or without work-flow) in nature.
They can also be business (e.g. Underwriting or Funding) or infrastructure (e.g. E-mail or
Job Scheduling).
Identify and document the state and behavior of the objects used by services identified in the
previous step.
It's important to keep the model at a high-level initially focusing on the core elements of the
business domain.
From a project management stand-point, a real-world DDD implementation project comprises the
same phases as any other software development project. These phases include:
Model the domain
Design
Development
Unit and Integration Testing
Refine and refactor the domain model based on the design and development (Continuous
Integration (CI) of model concepts).
Repeat the above steps using the updated domain model (CI of domain implementation).
An agile software development methodology is a great fit here because agile methodologies
focus on the delivery of business value just like DDD focuses on the alignment of software
system with business model. Also, with the iterative nature of DDD, agile methodologies such as
SCRUM or DSDM are better frameworks to manage the project. Using SCRUM (for project
management) and XP (for software development purposes) methodologies is a good combination
for managing a DDD implementation project.
This project management model of DDD iteration cycle is shown in Figure 1 below.
Cloud Native Java Aug 30, 2016
SPONSORED CONTENT
Node.js Performance CheatSheetManaging Node.js applications
has become increasingly difficult
as the environments are more
complex than ever. In this cheat
sheet, you'll find actionable tips to
help you effectively monitor and
manage your complex Node.js
environment.
Top 10 Java PerformanceProblemsAs Java applications become
more distributed and complex,
finding and diagnosing
performance issues becomes
harder and harder. Download this
eBook and learn how to
troubleshoot and diagnose some
of the most common performance
issues in Java today.
RELATED CONTENT
Modern Java Component Design withSpring 4.3 Aug 30, 2016
SpringOne Platform 2016 TechnicalKeynote - 2 Aug 26, 2016
Updated Spring 5.0 Roadmap and ReactiveStory Presented at SpringOne Aug 08, 2016
Apache Tomcat Roadmap Aug 26, 2016
SpringOne Platform 2016 TechnicalKeynote - 5 Aug 26, 2016
SpringOne Platform 2016 TechnicalKeynote - 3 Aug 26, 2016
Faster Ruby, JS and OtherLanguages Using Graal and Truffle Aug 19, 2016
Creating RESTful Services with T4Based on Model and Interfaces Aug 19, 2016
Impact of Java EE 8 Hiatus on Tomcat 9Highlighted at SpringOne Aug 04, 2016
Escaping the Bikeshed with JSON-API Aug 17, 2016
Page 3 of 32 Assembled by RunPDF.com
Figure 1. DDD Iteration cycle diagram (Click on the screen shot to open a full-size view.)
Domain driven design effort begins where domain modeling ends. Ramnivas Laddad
recommends the following steps on how to go about implementing a domain object model. He
emphasizes on putting more focus on domain objects than services in the domain model.
Start with domain entities and domain logic.
Start without a service layer initially and only add services where the logic doesn't belong in
any domain entity or value object.
Use Ubiquitous Language, Design by Contract (DbC), Automated Tests, CI and Refactoring
to make the implementation as closely aligned as possible with the domain model.
From the design and implementation stand-point, a typical DDD framework should support the
following features.
It should be a POJO (or POCO if your company is a .NET shop) based framework.
It should support the design and implementation of a business domain model using the DDD
concepts.
It should support concepts like Dependency Injection (DI) and Aspect Oriented Programming
(AOP) out of the box. (Note: These concepts are explained in more detail later in the article).
Integration with unit testing frameworks such as JUnit, TestNG, Unitils etc.
Good integration with other Java/Java EE frameworks like JPA, Hibernate, TopLink etc.
Sample Application
The sample application used in this article is a home loan processing system and the business
use case is to approve the funding request of a home loan (mortgage). When a loan application
is submitted to a mortgage lending company, it first goes through the Underwriting process where
the underwriters approve or deny the loan request based on customer's income details, credit
history and other factors. If the loan application is approved by underwriting group, it goes
through Closing and Funding steps in the loan approval process.
Funding module in the loan processing system automates the process of disbursement of funds
to the borrower. The funding process typically starts with mortgage lender (typically a bank)
forwarding the loan package to a title company. The title company then reviews the loan package
and schedules a date with seller and buyer of the property for closing the loan. Borrower and the
seller meet with the closing agent at the title company to sign the paperwork to transfer the title
of the property.
Architecture
A typical enterprise application architecture consists of the following four conceptual layers:
User Interface (Presentation Layer): Responsible for presenting information to the user
and interpreting user commands.
Application Layer: This layer coordinates the application activity. It doesn't contain any
business logic. It does not hold the state of business objects, but it can hold the state of an
application task's progress.
Domain Layer: This layer contains information about the business domain. The state of
business objects is held here. Persistence of the business objects and possibly their state is
delegated to the infrastructure layer.
Infrastructure Layer: This layer acts as a supporting library for all the other layers. It
provides communication between layers, implements persistence for business objects,
contains supporting libraries for the user interface layer, etc.
Let's look at the application and domain layers in more detail. The Application layer:
is responsible for the navigation between the UI screens in the application as well as the
interaction with the application layers of other systems.
can also perform the basic (non-business related) validation on the user input data before
transmitting it to the other (lower) layers of the application.
doesn't contain any business or domain related logic or data access logic.
doesn't have any state reflecting a business use case but it can manage the state of the
user session or the progress of a task.
JUnit 5 - An Early Test Drive - Part 2 Aug 15, 2016
Page 4 of 32 Assembled by RunPDF.com
The domain layer:
is responsible for the concepts of business domain, information about the business use case
and the business rules. Domain objects encapsulate the state and behavior of business
entities. Examples of business entities in a loan processing application are Mortgage,
Property, and Borrower.
can also manage the state (session) of a business use case if the use case spans multiple
user requests (e.g. loan registration process which consists of multiple steps: user entering
the loan details, system returning the products and rates based on the loan parameters,
user selecting a specific product/rate combination, and finally the system locking the loan for
that rate).
contains service objects that only have a defined operational behavior which is not part of
any domain object. Services encapsulate behavior of the business domain that doesn't fit in
the domain objects themselves.
is the heart of the business application and should be well isolated from the other layers of
the application. Also, it should not be dependent on the application frameworks used in the
other layers (JSP/JSF, Struts, EJB, Hibernate, XMLBeans and so-on).
Figure 2 below shows the different architecture layers used in the application and how they
relate to DDD.
Figure 2. Layered Application Architecture diagram (Click on the screen shot to open a full-size
view.)
Following design aspects are considered as the main ingredients of the current DDD
implementation recipe:
Object Oriented Programming (OOP)
Dependency Injection (DI)
Aspect Oriented Programming (AOP)
OOP is the most important element in the domain implementation. Domain objects should be
designed using Plain Java Classes and Interfaces by taking advantage of OOP concepts like
inheritance, encapsulation, and polymorphism. Most of the domain elements are true objects with
both State (attributes) and Behavior (methods or operations that act on the state). They also
correspond to real world concepts and can fit right in with OOP concepts. Entities and Value
Objects in DDD are classic examples of OOP concepts since they have both state and behavior.
In a typical Unit of Work (UOW), domain objects need to collaborate with other objects whether
they are Services, Repositories or Factories. Domain objects also need to manage other
concerns such as domain state change tracking, auditing, caching, transaction management
(including transaction retry) which are cross-cutting in nature. These are reusable non-domain
related concerns that typically tend to be scattered and duplicated all over the code including the
domain layer. Embedding this logic in the domain objects leads to tangling and cluttering of the
domain layer with non-domain related code.
When it comes to managing the code dependencies without tight-coupling between objects and
isolating cross-cutting concerns, OOP alone cannot provide an elegant design solution for
domain driven design and development. This is where design concepts like DI and AOP can be
Page 5 of 32 Assembled by RunPDF.com
used to complement OOP to minimize tight coupling, enhance modularity and better manage the
cross-cutting concerns.
Dependency Injection
DI is a great way to move the configuration and dependency code out of the domain objects.
Also, the design dependency of domain classes on Data Access Object (DAO) classes and
service classes on domain classes makes DI a "must have" in DDD implementation. DI facilitates
a cleaner and loosely coupled design by injecting the other objects such as Repositories and
Services into Domain Objects.
In the sample application, the service object (FundingServiceImpl) uses DI to inject the Entity
objects (Loan, Borrower and FundingRequest). Also, Entities reference Repositories via DI.
Similarly, other Java EE resources like DataSource, Hibernate Session Factory and Transaction
Manager are injected into Service and Repository objects.
Aspect Oriented Programming
AOP helps in an even better design (i.e. less cluttering in the domain model) by removing the
cross-cutting concerns code like auditing, domain state change tracking etc from the domain
objects. It can be used to inject collaborating objects and services into domain objects especially
the objects that are not instantiated by the container (such as the persistence objects). Other
aspects in the domain layer that could use AOP are caching, transaction management and role
based security (authorization).
Loan processing application uses custom Aspects to introduce data caching into the Service
objects. Loan product and interest rate information is loaded from the database table once (the
first this information is requested by the client) and is then stored in an object cache
(JBossCache) for subsequent product and rate lookups. Product and rate data is frequently
accessed but it's not updated that regularly, so it's a good candidate for caching the data instead
of hitting the back-end database every time.
The role of DI and AOP concepts in DDD was the main topic in a recent discussion thread. The
discussion was based on a presentation by Ramnivas Laddad where he made the assertion that
DDD cannot be implemented without help of AOP and DI. In the presentation, Ramnivas talked
about the concept of "fine grained DI" using AOP to make domain objects regain smart behavior.
He mentioned that domain objects need access to other fine grained objects to provide rich
behavior and a solution to this is to inject Services, Factories, or Repositories into Domain
Objects (by using Aspects to inject dependency at constructor or setter invocation time).
Chris Richardson also discussed about using DI, objects, and Aspects to improve the application
design by reducing coupling and increasing modularity. Chris talked about "Big Fat Service" anti-
pattern which is the result of coupling, tangling and scattering of the application code and how to
avoid it using DI and AOP concepts.
Annotations
A recent trend to define and manage Aspects and DI is to use Annotations. Annotations help in
minimizing the required artifacts for implementing the remote services such as EJB or Web
Services. They also simplify the configuration management tasks. Spring 2.5, Hibernate 3 and
other frameworks take full advantage of Annotations to configure the components in different
layers of a Java enterprise application.
We should take advantage of annotations to generate the boiler plate code where it adds value
in terms of flexibility. At the same time, annotations should be used with some caution. They
should be used where they are not confusing or misleading in understanding the actual code. A
good example of using Annotation is Hibernate ORM mapping where it adds value to specify the
SQL table or column name right next to the class or attribute name. On the other hand, details
like JDBC driver configuration (driver name, jdbc url, user name, and password) are better suited
to be stored in an XML file rather than using Annotations. This is based on the assumption that
the database is in the same context. If significant transformations are required between the
domain model and the database tables, then the design should take that concern into
consideration.
Java EE 5 provides JPA annotations like @Entity, @PersistenceUnit, @PersistenceContext, etc.
to add persistence details to plain Java classes. In the context of domain modeling, Entity,
Repository and Service are good candidates for using Annotations.
@Configurable is Spring's way of injecting Repository and Services into a Domain Object. Spring
framework extends the "Domain Object DI" idea beyond the @Configurable annotation.
Ramnivas recently blogged about the latest improvements in upcoming Spring 2.5.2 release
Page 6 of 32 Assembled by RunPDF.com
(available starting with project snapshot build 379). There are three new aspects
(AnnotationBeanConfigurerAspect, AbstractInterfaceDrivenDependencyInjectionAspect, and
AbstractDependencyInjectionAspect) to provide simple and more flexible options for Domain
Object DI. Ramnivas said the main reason behind introducing the middle aspect
(AbstractInterfaceDrivenDependencyInjectionAspect) is to allow domain-specific annotations and
interfaces to play a role. Spring also provides other annotations like @Repository, @Service,
and @Transactional to help in the design of the domain classes.
Some of the annotations used in the sample application, Entity objects (Loan, Borrower, and
FundingRequest) use @Entity annotation. These objects also use @Configurable annotation to
wire the Repository objects. And the Service classes use @Transactional annotation to decorate
the service methods with transactional behavior.
Domain model and Security
Application security in the domain layer ensures only authorized clients (human users or other
applications) are calling the domain operations as well as accessing the domain state.
Spring Security (a sub-project in Spring Portfolio) provides a fine-grained access control in both
presentation (URL based) and domain (Method Level) layers of the application. The framework
uses Spring's Bean Proxy to intercept method invocation and apply security constraints. It offers
a role-based declarative security for Java objects using MethodSecurityInterceptor class. There
is also instance level security in the form of Access Control Lists (ACL's) for domain objects to
control the user access at the instance level.
The main advantage of using Spring Security for managing the authorization requirements in the
domain model is that the framework has a non-invasive architecture so we can have a clean
separation between the domain and security aspects. Also, the business objects are not
cluttered with security implementation details. We can write common security rules in one place
and apply them (using AOP techniques) wherever they need to be implemented.
In domain and service classes, authorization is managed at the class method invocation level.
For example, the "loan approval" method in an Underwriting domain object can be invoked by
any user with an "Underwriter" role for loans up to 1 million dollars whereas the approval method
in the same domain object for loan applications with a loan amount greater than 1 million dollars
can only be called by a user with "Underwriting Supervisor" role.
The following table is a summary of various application security concerns in each layer of the
application architecture.
Table 1. Security Concerns in Various Application Layers
Layer Security Concern
Client/ControllerAuthentication, Web Page (URL) Level Authorization
Facade Role based authorization
Domain Domain instance level authorization, ACL
Database DB object level authorization (Stored procedures, Stored functions, Triggers)
Business Rules
Business rules are an important part of the business domain. They define data validation and
other constraints that need to be applied on domain objects in specific business process
scenarios. Business rules typically fall into the following categories:
Data validation
Data transformation
Business decision-making
Process routing (work-flow logic)
The context is very important in DDD world. Context specificity dictates the domain object
collaboration as well as other run-time factors like what business rules to apply etc. Validation
and other business rules are always processed in a specific business context. This means the
same domain object, in a different business context, will have to process different set of business
rules. For example, some attributes of a loan domain object (such as loan amount and interest
rate) cannot be changed after the loan has been through the Underwriting step in the loan
approval process. But the same attributes can be changed when the loan is just registered and
locked for a specific interest rate.
Even though all the domain specific business rules should be encapsulated in the domain layer,
some application designs put the rules in facade classes, which leads to domain classes
becoming "anemic" in terms of business rules logic. This may be an acceptable solution in small
Page 7 of 32 Assembled by RunPDF.com
size applications, but it is not recommended for mid-size to large enterprise applications that
contain complex business rules. A better design option is to put the rules where they belong,
inside the domain objects. If a business rule logic spans two or more Entity objects, then it should
become part of a Service class.
Also, if we are not diligent in the application, design business rules will end up being coded in the
form of several switch statements in the code. And over time as the rules get more complex,
developers don't take time to refactor the code to move "switch" statements into a more
manageable design. Hardcoding the complex routing or decision-making rules logic in the
classes leads to longer methods in the classes, code duplication, and ultimately a rigid
application design which will become a maintenance nightmare in the long run. A good design is
to place all the rules (especially complex rules that change frequently as the business strategy
changes) into a Rules engine (using a rules framework like JBoss Rules, OpenRules, or
Mandarax) and invoke them from the domain classes.
Validation rules are usually implemented in different languages like Javascript, XML, Java code,
and other scripting languages. But due to the dynamic nature of business rules, scripting
languages such as Ruby, Groovy, or Domain Specific Languages (DSL) are a better choice to
define and manage these rules. Struts (Application layer), Spring (Service) and Hibernate (ORM)
all have their own validation modules where we can apply the validation rules on the incoming or
outgoing data objects. In some cases, validation rules can also be managed as Aspects (link
AOP rules article here) that can be weaved into different layers (e.g. Service and Controller) of
the application.
It's important to keep in mind the unit testing aspect when writing the domain classes to manage
business rules. Any changes in the rules logic should be easily unit testable in isolation.
The sample application includes a business rule set to validate the loan parameters are within
the allowed product and rate specifications. The rules are defined in a scripting language
(Groovy) and are applied on the loan data passed to FundingService object.
Design
From a design stand-point, the domain layer should have a well defined boundary to avoid the
corruption of the layer from non-core domain layer concerns such as vendor-specific
translations, data filtering, transformations, etc. Domain elements should be designed to hold the
domain state and behavior correctly. Different domain elements are structured differently based
on state and behavior. Table 2 below shows the domain elements and what they contain.
Table 2. Domain elements with state and behavior
Domain Element State/Behavior
Entity, Value Object, AggregateState and Behavior
Data Transfer Object State only
Service, Repository Behavior only
Entities, Value Objects, and Aggregates which contain both state (data) and behavior
(operations), should have clearly defined state and behavior. At the same time, this behavior
should not extend beyond the limits of the object's boundaries. Entities should do most of the
work in the use case acting on their local state. But they shouldn't know about too many
unrelated concepts.
Good design practice is to only include the getters/setters for the attributes that are required to
encapsulate the state of domain objects. When designing the domain objects, only provide setter
methods for those fields that can change. Also, the public constructors should contain only the
required fields instead of a constructor with all the fields in the domain class.
In most of the use cases, we don't really have to be able to change the state of an object directly.
So, instead of changing the internal state, create a new object with the changed state and return
the new object. This is sufficient in these use cases and it also reduces design complexity.
Aggregate classes hide the usage of collaborating classes from callers. They can be used for
encapsulating complex, intrusive, and state-dependent requirements in the domain classes.
Design Patterns that Support DDD
There are several design patterns that help in domain driven design and development. Following
is a list of these design patterns:
Domain Object (DO)
Data Transfer Object (DTO)
Page 8 of 32 Assembled by RunPDF.com
DTO Assembler
Repository: The Repository contains domain-centric methods and uses the DAO to interact
with the database.
Generic DAO's
Temporal Patterns: These patterns add time dimension to rich domain models. Bitemporal
framework, which is based on Martin Fowler's Temporal Patterns, provides a design
approach to dealing with bitemporal issues in the domain models. The core domain objects
and their bitemporal properties can be persisted using an ORM product such as Hibernate.
Other design patterns that are used in DDD include Strategy, Facade, and Factory. Jimmy
Nilsson discussed Factory as one of the domain patterns in his book.
DDD Anti-Patterns
On the flip side of the best practices and design patterns, there are some DDD smells that
architects and developers should watch out for when implementing the domain model. As a result
of these anti-patterns, domain layer becomes the least important part in application architecture
and facade classes assume a more important role in the model. Following are some of these
anti-patterns:
Anemic domain objects
Repetitive DAO's
Fat Service Layer: This is where service classes will end up having all the business logic.
Feature Envy: This is one of the classic smells mentioned in Martin Fowler's book on
Refactoring where the methods in a class are far too interested in data belonging to other
classes.
Data Access Objects
DAO's and Repositories are also important in domain driven design. DAO is the contract
between relational database and the application. It encapsulates the details of database CRUD
operations from the web application. On the other hand, a Repository is a separate abstraction
that interacts with the DAOs and provides "business interfaces" to the domain model.
Repositories speak the Ubiquitous Language of the domain, work with all necessary DAOs and
provide data access services to the domain model in a language the domain understands.
DAO methods are fine-grained and closer to the database while the Repository methods are
more coarse-grained and closer to the domain. Also one Repository class may have multiple
DAO's injected. Repositories and DAO's keep the domain model decoupled from dealing with the
data access and persistence details.
The domain objects should depend only on Repository interfaces. This is the reason why
injecting the Repository instead of a DAO results in a much cleaner domain model. DAO classes
should never be called directly from the client (Services and other consumer classes). The
clients should always call the domain objects which in turn should call the DAO's for persisting
the data to the data store.
Managing the dependencies between domain objects (for example, the dependency between an
Entity and its Repository) is a classic problem that developers often run into. The usual design
solution to this problem is to have the Service or Facade class call a Repository directly and
when invoked the Repository would return the Entity object to the client. This design eventually
leads to the afore-mentioned Anemic Domain Model where facade classes start accumulating
more business logic and domain objects become mere data carriers. A good design is to inject
Repositories and Services into domain objects using DI & AOP techniques.
Sample application follows these design principles in implementing the loan processing domain
model.
Persistence
Persistence is an infrastructural aspect from which the domain layer should be decoupled. JPA
provides this abstraction by hiding the details of the persistence implementation from the
classes. It is annotation driven so no XML mapping files are required. But at the same time, the
table and column names are embedded in the code which may not be a flexible solution in some
cases.
With grid computing products such as Oracle Coherence, WebSphere Object Grid, and
GigaSpaces that offer data grid solutions, the developers don't even need to think about a
RDBMS when they model and design the business domain. The database layer is abstracted
from domain layer in the form of an in-memory Object/Data Grid.
Page 9 of 32 Assembled by RunPDF.com
Caching
When we talk about the state (data) of the domain layer, we have to talk about the aspect of
caching. Frequently accessed domain data (such as products and rates in a mortgage loan
processing application) are good candidates for caching. Caching speeds up the performance
and reduces the load on the database server. Service layer is ideal for caching the domain state.
ORM frameworks like TopLink and Hibernate also provide data caching.
Loan processing sample application uses JBossCache framework to cache product and rate
details to minimize the database calls and improve application performance.
Transaction Management
Transaction management is important to keep the data integrity and to commit or rollback the
UOW as a whole. There has always been a debate about where the transactions should be
managed in the application architecture layers. There are also the cross-entity transactions (that
span multiple domain objects in the same UOW) that affect the design decision of where the
transactions should be managed.
Some developers prefer managing the transactions in the DAO classes which is a poor design.
This results in too fine-grained transaction control which doesn't give the flexibility of managing
the use cases where the transactions span multiple domain objects. Service classes should
handle transactions; this way even if the transaction spans multiple domain objects, the service
class can manage the transaction since in most of the use cases the Service class handles the
control flow.
FundingServiceImpl class in the sample application manages transactions for the funding
request and executes multiple database operations by calling the Repositories and commits or
rolls back all database changes in a single transactions.
Data Transfer Objects
DTO's are also an important part of the design in an SOA environment where the Domain object
model structurally is not compatible with the messages that are received and sent from a
business service. The messages are typically defined and maintained in as XML Schema
Definition documents (XSD's) and it's a common practice to write (or code generate) DTO objects
from the XSD's and use them for data (message) transfer purposes between domain and SOA
service layers. Mapping the data from one or more domain objects to a DTO will become a
necessary evil in distributed applications where sending the domain objects across the wire may
not be practical from a performance and a security stand-point.
From a DDD perspective, DTO's also help maintain the separation between Service and UI
layers where DO's are used in the domain and service layers and DTO's are used in the
presentation layer.
Dozer framework is used for the assembly of one or more domain objects into a DTO object. It is
bi-directional which saves a lot of extra code and time when converting domain objects into
DTO's and vice-versa. The 2-way mapping between DO and DTO objects helps eliminate the
separate DO -> DTO and DTO -> DO translation logic. The framework also correctly handles the
type and array conversion.
The sample application uses Dozer mapping files (XML) to split the FundingRequestDTO object
into Loan, Borrower, and FundingRequest Entity objects when the request comes in for fund
processing. The mapping also takes care of the aggregation of the funding response data from
the Entities into a single DTO object on the way back to the client.
DDD Implementation Frameworks
Frameworks like Spring and Real Object Oriented (ROO), Hibernate, and Dozer aid in designing
and implementing a domain model. Other frameworks that support DDD implementation are
JMatter, Naked Objects, Ruby On Rails, Grails, and Spring Modules XT Framework.
Spring takes care of instantiating and wiring together the domain classes such as Services,
Factories, and Repositories. It also injects Services into Entities using @Configurable annotation.
This annotation is Spring specific, so other options for achieving this injection is to use
something like Hibernate Interceptor.
ROO is a DDD implementation framework built on "domain first and infrastructure second"
philosophy. The framework was developed to reduce the boiler-plate coding of the patterns
found in web application development. When using ROO, we define the domain model, and then
the framework (based on Maven Archetypes) generates the code for Model-View-Controller
(MVC), DTO's, Business Layer Facade and DAO layers. It even generates the stubs for unit and
Page 10 of 32 Assembled by RunPDF.com
integration tests.
ROO has some very useful practical implementation patterns. For example, it distinguishes the
state managed fields, the persistence layer uses field-level access, and the public constructors
only reflect the mandatory fields.
Development
A model is no good without the actual implementation. The implementation phase should include
automating the development tasks as much as possible. To see what tasks can be automated,
let's look at a typical use case involving the domain model. Following is the list of steps in the use
case:
Request In:
Client calls a Facade class sending data as an XML document (which is XSD compliant);
Facade class initiates a new transaction for the UOW.
Run validations on the incoming data. These validations include the primary (basic/data
type/field level checks) and business validations. If there are any validation errors, raise
appropriate exceptions.
Translate the descriptions to codes (to be domain friendly).
Make the data formatting changes to be domain model friendly.
Make any separation of attributes (like splitting a customer name into first and last name
attributes in a Customer Entity object).
Disassemble the DTO data into one or more domain objects.
Persist the state of domain objects.
Response Out:
Get the state of domain object(s) from datastore.
Cache the state if necessary.
Assemble the domain object(s) into application friendly data objects (DTO).
Make any merge or separation of data elements (such as combining first and last names into
single customer name attribute).
Translate the codes into descriptions.
Make the data formatting changes necessary to address the client data usage requirements.
Cache the DTO state if necessary
Transaction commits (or rolls back if there was an error) as the control flow exits.
The following table shows different objects that carry the data from one layer to another in the
application.
Table 3. Data flow through the application layers
Layer From Object To ObjectFramework
DAO Database Table(s)DO Hibernate
Domain DelegateDO DTO Dozer
Data Transfer DTO XML JAXB
As you can see there are few layers in the application architecture where same data flows
through in different forms (DO, DTO, XML, etc). Most of these objects (Java or XML) that hold
data as well as other classes like DAO, DAOImpl, and DAOTest are infrastructural in nature.
These classes and XML files that have boiler-plate code and structure are great candidates for
code generation.
Code Generation
Frameworks like ROO also create a standard and consistent project template (using Maven
plugin) for new projects. Using a pre-generated project template, we can achieve consistency in
the directory structure on where to store the source and test classes, configuration files, and
dependencies on internal and external (third-party) component libraries.
It could be overwhelming when we consider the myriad of classes and configuration files needed
to develop a typical enterprise software application. Code generation is the best way to go about
this problem. Code generation tools typically use some kind of template framework to define the
templates or mappings from which a code generator can generate the code. Eclipse Modeling
Framework (EMF) has several sub-projects that aid in the code generation of various artifacts
required in a web application project. Model Driven Architecture (MDA) tools like AndroMDA use
EMF to generate the code based on architecture models.
When it comes to writing the delegate classes in domain layer I have seen developers writing
Page 11 of 32 Assembled by RunPDF.com
these classes manually (mostly writing the first one from scratch and then following "Copy And
Paste" pattern to create the required delegate classes for other domain objects. Since most of
these classes are basically facades to domain classes they are good candidates for code
generation. Code generation option is a good long-term solution even though it involves some
initial investment (in terms of coding and time) to build and test the code generator (engine).
For the test classes generated, a good option is to create abstract methods for the methods with
complex business logic in the main class that need to be unit tested. This way, developers can
extend the generated base test class and implement custom business logic which cannot be
auto-generated. The same goes for any test method that has testing logic which cannot be auto-
created.
Scripting languages are a better choice for writing code generators as they have less overhead
and they support template creation and customization options. If we take advantage of code
generation in a DDD project, we only need to write a few classes from scratch. The artifacts that
must be created from scratch include:
XSD
Domain Object
Service
Once we define the XSD and Java classes, we can code generate all or most of the following
classes and configuration files:
DAO interface and implementation class
Factories
Repositories
Domain Delegate (if needed)
Facade (including EJB and WebService classes)
DTO's
Unit Tests for the above classes (including test class and test data)
Spring configuration files
Table 4 below lists different layers in a web application architecture and what artifacts (Java
classes or XML files) can be generated in that layer.
Table 4: Code generation in DDD implementation project
Layer/FunctionPattern Code You Write Generated Code Framework
Data Access DAO/Repository DAO Interface,
DAO Implementation class,
DAOTest,
Test Seed Data
Unitils,
DBUnit
Domain DO Domain class DomainTest
Persistence ORM Domain Class ORM Mappings,
ORM Mapping Test
Hibernate,
ORMUnit
Data Transfer DTO XSD DTO JAXB
DTO AssemblyAssembler Mapping DO-DTO Mapping Dozer
Delegate Business DelegateCode to translate DO's to DTO's
Facade Facade Remote Service,
EJB,
Web Service
Controller MVC Controller Mapping Files Struts/Spring MVC
Presentation MVC View configuration files Spring MVC
Delegate layer is the only layer that has knowledge of both Domain Objects and DTO's. Other
layers such as Persistence layer should be unaware of DTO's.
Refactoring
Refactoring is changing or restructuring the application code without changing the functionality
or behavior of the application. Refactoring can be either design or code related. Design
refactoring is done to continually refine the model and refactor the code to improve the domain
model.
Refactoring plays an important role in the DDD project due to its iterative and evolutionary
nature of domain modeling. One way to integrate refactoring tasks into the project is to add it in
each iteration of the project before calling the iteration done. Ideally, refactoring should be done
before and after every development task.
Page 12 of 32 Assembled by RunPDF.com
Refactoring should be done with strict discipline. Use the combination of refactoring, CI, and unit
testing to make sure the code changes didn't break any functionality and at the same time the
changes did help with the intended code or performance improvements.
Automated tests play a vital role in refactoring the application code. Without good automated
developer tests and Test Driven Development (TDD) practices, refactoring can be counter-
productive since there will be no automated way to verify that the design and code changes
made as part of refactoring effort didn't change the behavior or break the functionality.
Tools like Eclipse help in implementing the domain model in an iterative way with refactoring as
part of the development effort. Eclipse has features like extracting or moving a method to a
different class or pushing down a method to a subclass. There are also several code analysis
plugins for Eclipse that can help in managing the code dependencies and identifying the DDD
anti-patterns. I rely on plugins like JDepend, Classycle, and Metrics when I do the design and
code review of projects, to assess the quality of domain and other modules in the application.
Chris Richardson talked about applying code refactoring to transform a procedural design into
an OO design using refactoring features provided by Eclipse.
Unit Testing/Continuous Integration
One of the goals we talked about earlier is that the domain classes should be unit testable
(during the initial development as well as later when refactoring the existing code) without too
many dependencies on the container or other infrastructure code. TDD approach helps the team
in finding any design problems early in the project as well as verifying that the code is in
alignment with domain model. DDD is ideal for Test-First development because the state and
behavior are contained in domain classes and it should be easy to test them in isolation. It is
important to test the state and behavior of domain model and not focus too much on the
implementation details of data access or persistence.
Unit testing frameworks like JUnit or TestNG are great tools to implement and manage the
domain model. Other testing frameworks like DBUnit and Unitils can also be used to test domain
layer especially to inject test data into DAO classes. This will minimize writing extra code for
populating test data in unit test classes.
Mock objects also help in testing the domain objects in isolation. But it's important to not go crazy
with using mock objects in the domain layer. If there are other easy ways to test domain classes,
you should use those options instead of using mock objects. For example, if you can test an
Entity class using a real DAO class in the back-end (instead of a mock DAO implementation) with
an in-memory HSQL database instead of the real database; it will make the domain layer unit
tests run quicker which is the main idea behind using mock objects any way. This way, you will be
testing the collaboration (interaction) between domain objects as well as the state (data)
exchanged between them. With mock objects, we will only be testing the interaction between the
domain objects.
All unit and integration tests created during the development phase (with or without using TDD
practices) will become part of the automated test suite once the development tasks are done.
These tests should be maintained and executed frequently in the local and higher development
environments to find if the new code changes introduced any bugs into domain classes.
Eric Evans covers CI in his book saying that CI effort should always be applied within a Bounded
Context and it should include the synchronization of people as well as code. CI tools like
CruiseControl and Hudson can be used to set up an automatic build and test environment to run
the application build script (created using a build tool such as Ant or Maven) to checkout the
code from a SCM repository (like CVS, Subversion etc), compile the domain classes (as well as
the other classes in the application) and if there are no build errors, then automatically run all the
tests (unit and integration). CI tools can also be setup to notify the project teams (via e-mail or
RSS feeds) if there are any build or test errors.
Deployment
Domain models are never static; they change as business requirements evolve during the
lifecycle of the project and new requirements come up in the new projects. Also, as you develop
and implement the domain model you constantly learn and improve, and you want to apply the
new knowledge to the existing model.
Isolation is the key when packaging and deploying the domain classes. Since domain layer has
dependencies on DAO layer on one side and Service Facade layer on the other (see the
application architecture diagram in Figure 2), it makes lot of sense to package and deploy the
domain classes as one or more modules to manage these dependencies elegantly.
Page 13 of 32 Assembled by RunPDF.com
While design patterns such as DI, AOP and Factories minimize the coupling between the objects
at design time and make the application modular, OSGi (formerly known as Open Services
Gateway initiative) addresses modularity at runtime. OSGi is becoming a standard mechanism to
package and distribute the enterprise applications. It nicely handles the dependencies between
the modules. We can also use OSGi for domain model versioning purposes.
We can package DAO classes in one OSGi bundle (the DAO bundle), the service facade classes
in another bundle (service bundle), so when DAO or Service implementations are modified or a
different version of the application is being deployed, thanks to OSGi, no application restarts are
required. We can also deploy two different versions of the same domain class if we have to
support the existing and new versions of certain domain objects for backward compatibility.
To take advantage of OSGi capabilities, the application objects have to be registered with OSGi
platform before being consumed (i.e. before the client can do a lookup for them). This means
that we have to use OSGi APIs to do the registration but we also have to deal with failure
scenarios as services are started and stopped using OSGi container. Spring Dynamic Modules
framework helps in this area by allowing any type of object to be exported and imported in the
application without any code changes.
Spring DM also provides test classes to run OSGi integration tests outside the container. For
example, AbstractOsgiTests can be used to run integration tests directly from the IDE. The setup
is handled by the testing infrastructure so we don't have to write a MANIFEST.MF file for the test,
or do any packaging or deployment. The framework supports most of the OSGi implementations
currently available (Equinox, Knopflerfish and Apache Felix).
Loan processing application uses OSGi, Spring DM, and Equinox container to manage the
module level dependencies and the deployment of domain and other modules.
LoanAppDeploymentTests shows the use of Spring DM test module.
Sample Application Design
The domain classes used in the loan processing sample application are listed below:
Entities:
Loan
Borrower
UnderwritingDecision
FundingRequest
Value Objects:
ProductRate
State
Services:
FundingService
Repositories:
LoanRepository
BorrowerRepository
FundingRepository
Figure 3 shows the domain model diagram for the sample application.
Page 14 of 32 Assembled by RunPDF.com
Figure 3. Layered Application Domain Model (Click on the screen shot to open a full-size view.)
Most of the DDD design concepts and techniques discussed in this article are applied in the
sample application. Concepts like DI, AOP, Annotations, Domain Level Security, and Persistence
are used. Also, I used several open source frameworks to help in DDD development and
implementation tasks. These frameworks are listed below:
Spring
Dozer
Spring Security
JAXB (Spring-WS for marshalling and unmarshalling the data)
Spring Testing (for unit and integration testing)
DBUnit
Spring Dynamic Modules
The domain classes in the sample application are deployed as an OSGi module using Equinox
and Spring DM frameworks. The following table shows the module packaging details for the
sample application.
Table 5. Packaging and Deployment Details
LayerDeployment
Artifact NameModule Contents Spring Configuration File(s)
Client/Controllerloanapp-
controller.jar
Controller, Client Delegate
classes
LoanAppContext-Controller.xml
Facade loanapp-
service.jar
Facade (Remote) Service,
Server Delegate classes, XSD's
LoanAppContext-RemoteServices.xml
Domain loanapp-
domain.jar
Domain classes, DAO,
Common DTO's
LoanAppContext-Domain.xml, LoanAppContext-
Persistence.xml
Framework loanapp-
framework.jar
Framework, Utility, Monitoring
(JMX) classes, Aspects
LoanAppContext-Framework.xml,
LoanAppContext-Monitoring.xml, LoanApp-
Aspects.xml
Conclusion
DDD is a powerful concept that will change the way modelers, architects, developers, and testers
will look at the software once the team is trained in DDD and start to apply "domain first and
infrastructure second" philosophy. As different stakeholders (from IT and business units) with
different backgrounds and areas of expertise are involved in the domain modeling, design and
implementation effort, to quote Eric Evans, "it's important not to blur the lines between the
philosophy of design (DDD) and the technical tool box that helps us fulfill it (OOP, DI, and AOP)".
Advancing Frontiers
This section covers some of the emerging approaches that impact the DDD design and
development. Some of these concepts are still evolving and it will be interesting to see how they
will affect DDD.
Architecture rules and Design by Contract enforcement plays an important role in the
governance and policy enforcement of domain model standards and implementation best
practices. Ramnivas talked about using the Aspects to enforce the rule of creating a Repository
object only through Factories; this is an easy to violate design rule in domain layer.
Domain Specific Languages (DSL) and Business Natural Languages (BNL) are gaining more
attention in the recent years. One can use these languages to represent business logic in the
domain classes. BNL's are powerful in the sense that they can be used to capture business
specifications, documenting the business rules, and as executable code as well. They can also
be used to create test cases to verify the system works as expected.
InfoQ Weekly Newsletter
Subscribe to our Weekly email newsletter to follow
all new content on InfoQ
Your email here SubscribeSubscribe
Page 15 of 32 Assembled by RunPDF.com
Personas Culture & Methods Architecture & Design Development Topics
Domain Modeling Domain Driven Design Pivotal Methodologies OSGi
Domain Specific Languages Code Generation AOP Architecture MDA Patterns
Dependency Injection Design Pattern Java Design Spring
Watch ThreadCommunity comments
Behavior Driven Development (BDD) is another interesting concept that has been discussed
lately. BDD helps focus development on the delivery of prioritized, verifiable business value by
providing a common vocabulary (Ubiquitous Language) that spans the divide between Business
and Technology. By using terminology focused on the behavioral aspects of the system rather
than testing, BDD attempts to help direct developers towards a focus on the real value to be
found in TDD at its most successful. If practiced correctly, BDD can be a great complement to
DDD where the development of domain objects is positively influenced by BDD concepts; after all
domain objects are supposed to encapsulate state and behavior.
Event Driven Architecture (EDA) is another area that could play a role in domain driven design.
For example, an event model to notify of any state change in the domain object instance would
help in handling the post-event processing tasks that need to be triggered when the state of a
domain object changes. EDA helps in encapsulating the event based logic from getting
embedded in core domain logic. Martin Fowler documented about Domain Event design pattern.
Resources
Domain-Driven Design, Tackling Complexity in the Heart of Software, Eric Evans, Addison
Wesley
Applying Domain-Driven Design and Patterns, Jimmy Nilsson, Addison Wesley
Refactoring to Patterns, Joshua Kerievsky, Addison Wesley
Can DDD be Adequately Implemented Without DI and AOP?
The sample application code can be downloaded here.
Please enter a subject
Message
Tell us what you think
Post MessagePost Message
It's wonderful! by Geng Laurence Posted Jun 13, 2008 12:21
Re: It's wonderful! by Geng Laurence Posted Jun 14, 2008 08:39
Re: It's wonderful! by Srini Penchikala Posted Jun 19, 2008 11:49
Re: It's wonderful! by James Bao Posted Jun 20, 2008 06:40
Re: It's wonderful! by Lindsay Holman Posted Jun 21, 2008 06:06
Re: It's wonderful! by Mattias Fagerström Posted Jul 04, 2008 05:44
Re: It's wonderful! by Srini Penchikala Posted Jul 08, 2008 06:31
Re: It's wonderful! by Srini Penchikala Posted Jun 25, 2008 01:18
Re: It's wonderful! by Lindsay Holman Posted Jun 29, 2008 04:06
Re: It's wonderful! by iury ribeiro Posted Jul 01, 2008 10:09
Re: It's wonderful! by Lindsay Holman Posted Jul 02, 2008 08:38
Re: It's wonderful! by Srini Penchikala Posted Jun 15, 2008 03:31
Re: It's wonderful! by Felipe Guarneri Posted Jul 25, 2012 01:11
One observation. by Leonard Petrica Posted Jun 13, 2008 03:12
No asserts in the tests by Peter Bona Posted Jun 13, 2008 04:39
Re: No asserts in the tests by Srini Penchikala Posted Jun 17, 2008 08:33
Mixed feelings by Yuriy Zubarev Posted Jun 13, 2008 07:47
Re: Mixed feelings by Lindsay Holman Posted Jun 18, 2008 03:14
Page 16 of 32 Assembled by RunPDF.com
Re: Mixed feelings by Srini Penchikala Posted Jun 19, 2008 11:40
Re: Mixed feelings by Yuriy Zubarev Posted Jun 20, 2008 08:30
Re: Mixed feelings by Lindsay Holman Posted Jun 21, 2008 06:04
Re: Mixed feelings by H S Posted Oct 26, 2009 04:40
What am I missing? by Rob Rudin Posted Jun 16, 2008 10:26
Re: What am I missing? by Phatthana Sitthideth Posted Jun 17, 2008 07:30
Re: What am I missing? by Srini Penchikala Posted Jun 25, 2008 01:10
Not even close to DDD by Kaushik Selvaraj Posted Jun 16, 2008 11:47
Re: Not even close to DDD by 李 引 Posted May 03, 2010 04:30
It *completely* misses the point... by Ronald Miura Posted Jun 17, 2008 11:34
Re: It *completely* misses the point... by Dustin Woods Posted Jun 17, 2008 11:46
Re: It *completely* misses the point... Not! by Geert Pante Posted Jun 17, 2008 05:29
Re: I *completely* agree by Dimitris Menounos Posted Jul 09, 2008 06:12
Re: I *completely* agree by Srini Penchikala Posted Jul 13, 2008 07:33
It's Great by Ravi Koda Posted Jun 17, 2008 08:55
Domain-Obects Java Classes not so intuitive by venkataramana madugundu Posted Jun 19, 2008 01:07
Misleading by Ilya Boyandin Posted Jun 22, 2008 09:33
DDD on 3 tiers (Differents JVM) by iury ribeiro Posted Jun 29, 2008 08:28
Re: DDD on 3 tiers (Differents JVM) by Srini Penchikala Posted Jul 03, 2008 03:30
Sculptor by Patrik Nordwall Posted Jul 01, 2008 02:20
Re: Sculptor by Srini Penchikala Posted Jul 03, 2008 05:52
Naming throwing by Eduardo Miranda Posted Jul 08, 2008 06:45
Re: Naming throwing by Srini Penchikala Posted Jul 13, 2008 07:26
What about the Grails approach? by Goran Oberg Posted Aug 03, 2008 07:21
Re: What about the Grails approach? by Soner Dastan Posted Sep 04, 2008 10:22
Re: What about the Grails approach? by Srini Penchikala Posted Sep 27, 2008 11:54
DDD and agile by Nima n Posted Oct 06, 2008 08:29
Re: DDD and agile by Srini Penchikala Posted Oct 21, 2008 09:56
Domain objects should not call CURD operations by Sandeep akhare Posted Sep 28, 2009 06:04
don't inject repository into model by Peng Sunny Posted Jan 19, 2010 08:53
Domain Layer uses the Infrastructure Layer. The layer below it. by Roy Oliver Posted May 19, 201008:38
A comment on the sample application by Enrique Molinari Posted Apr 23, 2012 11:08
Very bad example application, practically anti-DDD example by Georgi Danov Posted Sep 27, 201205:07
Re: Very bad example application, practically anti-DDD example by Roman Tmk Posted Jan 06,2013 02:02
DDD Modeling tool set by becky cortino Posted Oct 09, 2015 11:09
Reply Back to top
It's wonderful!
Jun 13, 2008 12:21 by Geng Laurence
It's really great!I have never seen so wonderful DDD implementation,especially it bases on
many mainstream frameworks such as hibernate,spring and so on. For the DDD,Eric Evans
gives us theoretic guidance,and I am sure,this simple application gives us practical
demonstration!Thank you Srini,I sure hope talking about some details of your article and
demo project after I seriously reviewed the project.
Page 17 of 32 Assembled by RunPDF.com
Reply Back to top
One observation.
Jun 13, 2008 03:12 by Leonard Petrica
In your class Loan you have CRUD functions like add(Loan loanData) which are applying to
other objects. I think is ok to have functions like add() which are operating for the current
instance of its class.
E.g.
public void add()
loanRepository.add(this);
Reply Back to top
No asserts in the tests
Jun 13, 2008 04:39 by Peter Bona
The article is great, but your sample application doesn't have asserts in the tests. How can
you test then if your application and domain model behaves correctly?
Reply Back to top
Mixed feelings
Jun 13, 2008 07:47 by Yuriy Zubarev
First of all I have to admit it's a great article and I enjoyed reading it. I also looked at the
source code and got mixed feelings about FundingServiceImpl class.
What's the advantage of
loan.add(newLoan);
over
newLoan.add();
for example?
You have "loan" object auto-wired in this class for a sole purpose of persisting "newLoan" as
it seems. A domain object is used as a service to persist another domain object of the same
type. May be I'm missing something but it doesn't feel quite right.
Thank you.
Reply Back to top
Re: It's wonderful!
Jun 14, 2008 08:39 by Geng Laurence
After reviewed your source code,and viewed other peoples' comments,I think it is not very well
that the domain object contains the CURD operation.I think it is the repository's responsibility.
In a aggregation,we should get objects' refference by navigation from the aggregation root,if
the we want to get the aggregation root,I think maybe we can provide a service.
Page 18 of 32 Assembled by RunPDF.com
Reply Back to top
Re: It's wonderful!
Jun 15, 2008 03:31 by Srini Penchikala
Hi Laurence, Thanks for the good comments. We, as enterprise developers (Java, .NET or
some other technology), focus too much on technical infrastructure details when designing
and developing applications. Techniques likes DI, Annotations and Code generation and
frameworks like Hibernate and Spring help move away from this paradigm and start focusing
more on business domain concerns. This article is an attempt to highlight this paradigm shift
and some best practices to implement it.
Reply Back to top
What am I missing?
Jun 16, 2008 10:26 by Rob Rudin
So I read all these grand declarations about DDD in the article, and then I look at the source
code, and the domain objects look awfully similar to so-called "anemic" domain objects which
are purportedly the scourge of software systems today (I was stunned to not find the requisite
link to Fowler's article on the subject). All I saw in these "rich" domain objects were
getters/setters for private attributes, some JPA annotations, and then some CRUD methods.
What's the big deal here?
And am I the only one who finds a method such as ProductRate.findProductRates() to be a bit
awkward in a grammatical sense? Does it really make sense to ask an instance of an object to
return a list of instances of its class type? Does anyone actually talk like that in their business
domain?
I also found the rhetoric at the top of the article to be conspicuously absent of any proof. "Not
investing in a domain model" will "not give the company a competitive advantage over other
companies because implementing business requirement changes in this architecture takes
too long"? Really? Where's your evidence to back this up?
I've used Spring/Hibernate/AOP/DI/TDD/CI/insert-your-favorite-buzzword/etc on a daily basis
for almost the past 5 years. I've followed the DDD movement with some curiousity, but if this
code sample is indicative of what it amounts to, I honestly don't understand what the fuss is
about.
Not even close to DDD
Jun 16, 2008 11:47 by Kaushik Selvaraj
There are lots of flaws on many levels.
>> Ramnivas Laddad where he made the assertion that DDD cannot be implemented
without help of AOP and DI.
You got it wrong. He said DDD cannot be "adequately implemented" without AOP. I have
posted on how you could use DDD without AOP here .
In your example code, none of your entities exhibit any encapsulation. Why do nearly
every field have a getter and setter exposed ? There is absolutely no domain business
methods in them. By just exposing CRUD methods in addition to getter/setters how can
Page 19 of 32 Assembled by RunPDF.com
Reply Back to top
you even call these domain objects? As a previous commenter had posted, are'nt these
still anemic?
Main concept behind Domain Driven Design is adding power to your domain classes
which you have not brought out at all. The examples are woefully shallow and cannot be
called as DDD examples at all. It is more an example of using spring's DI to inject
repositories into DDD. This article does not do justice to elegance and simplicity of DDD.
PS: Next time do some proper research before suggesting matching up various technologies
like OSGi with DDD/AOP/Spring etc. If you had any experience implementing either DDD or
OSGi you would know that using AOP in OSGi is severly limited. For e.g. aspects have to exist
in every single bundle where it has to be applied.
Reply Back to top
Re: What am I missing?
Jun 17, 2008 07:30 by Phatthana Sitthideth
@srini
nice article
@Rob
Yeah i know exactly what you mean by "what the fuss is about".
From my experiences 80% of these Spring/Hibernate/AOP/DI/TDD/CI/insert-your-favorite-
buzzword/etc projects don't need
DDD, it's just CRUD stuff.
As Eric Evans told me, DDD is for the 10%-20% percent of a system -> the truely complicated
sh*t.
That logic should be implemented by developers with strong design skills with the help of
open minded business analyst -> DDD is a sophisticated
technique for that.
My point is people tend to "ddd"-everthing, i.e.
if anyone tells you: "yeah our system is completely build upon/using DDD".....yeah ok, dream
on
None the less i think DDD is great stuff and definitely changes your view of perspective on
design/oo/teamwork.
Cheers
Phatthana
It *completely* misses the point...
Jun 17, 2008 11:34 by Ronald Miura
It seems that the author thinks a 'rich domain' is just 'inject DAOs into hibernate-mapped
objects'...
Looking at the source code, you can see the domain is just the plain old anemic model, with
DAOs (disguised as Repositories) injected.
At least in the examples, it doesn't make sense to use an instance of an entity to 'find' others,
which don't even have any relation (but its class) to the first. It is just being used as a
Repository (yeah, 'loan.add(newLoan)' IS stupid). And the domain logic, which should be
inside the entities, are externalized to the services, which are just glorified procedures.
Where is the 'insight'? Where is the 'objects model the business'? Where is the 'ubiquitous
Page 20 of 32 Assembled by RunPDF.com
Reply Back to top
language'?
If you are looking for a DDD example, take a look at the TimeAndMoney
(timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer', but
DDD is not about these, it's about capturing the business into objects. It isn't about CRUD, it's
about creating a language in code that matches the language in business (the core of it). It's
not about DI or Spring or Hibernate, it's about good, careful, insightful, relentless design.
Reply Back to top
Re: It *completely* misses the point...
Jun 17, 2008 11:46 by Dustin Woods
If you are looking for a DDD example, take a look at the TimeAndMoney
(timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer',
but DDD is not about these, it's about capturing the business into objects. It isn't about
CRUD, it's about creating a language in code that matches the language in business
(the core of it). It's not about DI or Spring or Hibernate, it's about good, careful,
insightful, relentless design.
"TimeAndMoney" makes a nice example of a library but it is far from any help at all when
building an entire application. I personally appreciate samples like these because is shows
the struggle that people have trying to apply DDD to real world problems. Without seeing
samples that have gotten the blessing of being DDD maybe DDD is for small libraries only
and doesn't apply to real world problems. It's easy to criticize Srini for sharing an
interpretation of DDD without opening yourself up to criticism with any sample of your own.
Re: It *completely* misses the point... Not!
Jun 17, 2008 05:29 by Geert Pante
If you are looking for a DDD example, take a look at the TimeAndMoney
(timeandmoney.domainlanguage.com/) library. No, it doesn't have a 'persistence layer',
but DDD is not about these, it's about capturing the business into objects. It isn't about
CRUD, it's about creating a language in code that matches the language in business
(the core of it). It's not about DI or Spring or Hibernate, it's about good, careful,
insightful, relentless design.
"TimeAndMoney" makes a nice example of a library but it is far from any help at all when
building an entire application. I personally appreciate samples like these because is
shows the struggle that people have trying to apply DDD to real world problems.
Without seeing samples that have gotten the blessing of being DDD maybe DDD is for
small libraries only and doesn't apply to real world problems. It's easy to criticize Srini for
sharing an interpretation of DDD without opening yourself up to criticism with any
sample of your own.
Hear, hear!
Having fooled around a bit myself with DDD and Java, I hoped to find a way to do three things
at once. Do DDD, avoid having to write a lot of duplicate boiler plate code, and keep
Spring/Hibernate/JUnit best practices. In doing so, I independently did the same discovery as
mr. Laddad: that AOP could be the missing link.
Indeed, Domain Driven Design is not tied to particular use of any framework, but if Hibernate
Page 21 of 32 Assembled by RunPDF.com
Reply Back to top
allows you to auto-generate DAO's and Repositories, and Spring's @Configurable
annotations with AOP allows you to auto-generate Factories, why wouldn't you go with the
flow?
Srini, I haven't checked your sample code thoroughly, but if you managed to get it all
connected and working, you did an excellent job, and it could provide the basis of a lot of our
future projects' designs.
Reply Back to top
Re: No asserts in the tests
Jun 17, 2008 08:33 by Srini Penchikala
Hi Peter, the unit tests for repository classes in the sample application have asserts inside
test methods, but you are right, the other test classes like LoanDomainTest should have
assert statements to verify state and behavior of domain objects. Also, if you are not already
using them, check out the additional assert's available in JUnit 4.4 version (Hamcrest asserts)
that add a great value to write and understand the assert logic in test methods. The other unit
testing guideline (which is a given to TDD followers) I try to follow is: No log.debug() or
log.error() method calls in the test classes, these should be replaced by appropriate assert
statements.
Reply Back to top
It's Great
Jun 17, 2008 08:55 by Ravi Koda
Thanks srini , This is what i am looking for my project.
Regards
Ravi
Re: Mixed feelings
Jun 18, 2008 03:14 by Lindsay Holman
A lot of people have mentioned the presence of CRUD methods on entities. I think this is a
fairly fundamental and very important aspect of DDD. The standard reference by Eric Evans
specifically states that you should not so this, and for a very good reason - it violates OO
design principles. A class should have one responsibility - persistence is not the responsibility
of an entity. While it farms the work out to a repository, an object's interface is just as
important to defining its responsibilities as the actual implementation.
It is extremely important that when undertaking this approach, the principle are kept in mind
and adhered to, as there are pitfalls waiting around the corner for those who don't.
As far as this being more an anaemic model, it is just because of the lack of hard core
business logic, and in itself isn't a problem. I don't see a problem with creating an anaemic
model from a DDD focus - at least the focus remains on the ubiquitous language.
I have just been involved in rescuing an SOA development. SOA services can be equated to
Eric Evans' idea of an application service. This is essentially a gateway into the business
logic, or the domain model. The development in question used JAXB to generate classes from
an xsd defining the service interface, and to populate objects from the xml message. The
services were extremely long, procedural, untestable methods which utilised the generated
classes. There was a layer of DAOs which also used these generated classes!! Something to
Page 22 of 32 Assembled by RunPDF.com
Reply Back to top
shift focus onto the domain and reinforce the fact that the SOA service is a thin layer whose
responsibility is integration - not business logic, would have avoided this.
I find it perplexing the number of SOA oriented developers who dismiss the idea of a rich
domain model. It seems to me to highlight a lack of understanding of the very essence of the
architecture they are implementing. These two approaches are not mutually exclusive - there
are distinct responsibilities in each layer.
Anyway, sorry about the waffle. This is my first post - hi everyone :)
Reply Back to top
Domain-Obects Java Classes not so intuitive
Jun 19, 2008 01:07 by venkataramana madugundu
Article is great in promoting Domain Driven Design, but the sample application code does not
express the domain concepts in java objects so well. For example, typically if there were no
automation, a bank which offers loans would typically have a LoanRegister (a loan folder
where each loan offered to a borrower is a page) for adding loans, updating loan info etc., So
as per my tastes, I would prefer to have a LoanRegister class on which methods like
addLoan(Loan), updateLoan(Loan) are exposed.
Reply Back to top
Re: Mixed feelings
Jun 19, 2008 11:40 by Srini Penchikala
Hi Yuriy, In the sample code, I wanted to show that the Entity objects are first-class citizens in
the domain model, they should also take care of the persisting the object's state (by calling a
repository or a DAO behind the scenes). Hence the call to the (wired) Loan entity object to
add a new loan record. You definitely want to use the domain object that has been associated
with DAO and other persistence resources (Hibernate SessionFactory etc) for creating and
updating the domain objects. In the example, I could have set the loan data in loan object
itself and then call loan.add() method w/o any input arguments (in which case, the domain
would act on its own instance).
Reply Back to top
Re: It's wonderful!
Jun 19, 2008 11:49 by Srini Penchikala
Hi Laurence, Domain objects should also be responsible for persisting the data (CRUD) in
addition to encapsulating the state and behavior of business domain entities and the
business logic. This way, clients can call the domain objects directly to create and manipulate
the domain state instead of relying on DAO's (which are infrastructure related classes in my
opinion) to take care of the persistence. Repositories, just like Entities, are domain objects
that are there for a purpose (of hiding the DAO implementation details behind the repository
classes). It's not always required for the Entities to call Repositories for CRUD functions. You
mention Aggregates and Services, these domain elements also have their own characteristics
on when to use them in domain model implementation. Eric Evans book is the best source for
learning more about all these domain elements.
Re: It's wonderful!
Jun 20, 2008 06:40 by James Bao
Hi Srini, I disagree with you that persistence is the responsibility of Domain objects. Stripping
out the data persisting logic from the domain object will make the code more readable and
Page 23 of 32 Assembled by RunPDF.com
Reply Back to top
maintainable.
Reply Back to top
Re: Mixed feelings
Jun 20, 2008 08:30 by Yuriy Zubarev
Another argument against having Persistence CRUD in domain objects is that you have a
circular dependency between "domain" and "repository" sub-packages. Circular dependency
is never a good thing regardless what kind of xDD you are practicing.
Re: Mixed feelings
Jun 21, 2008 06:04 by Lindsay Holman
Hi Yuriy,
I don't agree with you here. Circular dependencies just signify poor design. You can quite
legitimately have a domain object deal with persistence without circular references. Note, a
domain object which is an entiy should not be responsible for it's own persistence, a
repository object should (Not a DAO - this is rooted in deficiencies of EJB).
The underlying priciple is that the domain model is supposed to be a model of your business.
Does it make sense within that domain that you need to store and retrieve entities (say, a
loan). Absolutely yes, so this should be handled by a domain object. When you do store a
loan in the real world, do you get the loan to do it? No, you stick it in some sort of repository.
You can see here, the domain model is modelling the real world.
Typically, as per good design practice, the repository will be comprise an implementation and
an interface. All domain type references are confined to the domain layer (model).
The repository will then farm off the technology specific aspects to an object in the
infrastructure layer. This can be achieved through extension, delegation, template pattern
etc. Whatever way you choose, avoiding cirulcar references is just down to good design.
Typically in a hibernate environment for example, you would have a generic persistence
object, or a base persistence object for instance, which takes a class type and an object.
Though not really correct, but in line with many codebases, let's call this the
HibernateGenericDao class. It implements the interface GenericDao which defines the method
"add(String className, Object value)". In the domain model, we have a LoanRepositoryImpl
class which wraps GenericDao and implements LoanRepository. LoanRepository defines the
method add(Loan loan). The LoanRepositoryImpl.add(Loan loan) implementation delegates
to genericDao.add(Loan.getClass().getName(), loan). The HibernateGenericDao then takes
care of the hibernate specifics.
LoanRepository, Loan and LoanRepositoryImpl are members of the domain layer.
GenericDao and HibernateGenericDao are in the infrastructure layer. The domain layer
knows about the infrastructure layer, but the infrastructure layer knows nothing of the domain
layer. Perfectly layered, no circular references. If we want to change the persistence
mechanism, we plug in a different implementation of GenericDao into LoanRepositoryImpl.
Then, when we want to add a loan, a ui object may collect the details, an application service
object collates the details into a loan object, and call loanRepository.add(loan). I don't see
what is not clear about this implementation where persistence is handled by a domain object.Your browser (Apple Safari 5) is out of date. infoq.com recommends to update your browser for more security, comfort and the best experience on this site. x
Reply Back to top
what is not clear about this implementation where persistence is handled by a domain object.
Re: It's wonderful!
Jun 21, 2008 06:06 by Lindsay Holman
Persistence is absolutely the resposibility of a domain object - though an entity is not
responsible for its own persistence. (see my next post) This distinction between a domain
Page 24 of 32 Assembled by RunPDF.com
Reply Back to top
object and an entity object is crucial.
Reply Back to top
Misleading
Jun 22, 2008 09:33 by Ilya Boyandin
The sample app in this article has little to do with DDD. Chris Richardson's aop-ood is a way
better in that sense.
Reply Back to top
Re: What am I missing?
Jun 25, 2008 01:10 by Srini Penchikala
Hi Rob, In the sample application I focused more on the domain injection capabilities offered
by Spring framework and the role AOP in DDD. I agree with you that the Entity objects should
have more business logic than what the sample application shows. Also, the method to get
the list of ProductRate Value Object's should be in a Repository rather than the Value Object
itself.
Reply Back to top
Re: It's wonderful!
Jun 25, 2008 01:18 by Srini Penchikala
Hi James, if persistence is not the responsibility of Domain objects, where would CRUD logic
be handled? We don't want the clients to be calling DAO classes directly, they should be
ideally calling some business object which fronts the DAO because data access logic, in my
opinion, is an infrastructure concern that the client shouldn't know anything about.
Reply Back to top
Re: It's wonderful!
Jun 29, 2008 04:06 by Lindsay Holman
Hi Srini,
I really think having repositories and an infrastructure layer, and dao's and a data access
layer is a massive overcomplication of a simple problem. As far as why persistence belongs in
the domain model (re your reply to James), the simple explanation somes from the domain we
are trying to model. Given a traditional paper based office, we have a new client say, we
collect their details (at least enough to identify them), we create some sort of file for them,
then we store them in a repository of some sort, organised in such a way that we can easily
retrieve those details. This obviates the necessity for a repository in the domain layer.
The repository should farm off technical aspects of the persistence to an object in the
infratructure layer. There is no need for DAO's, or a data access layer. Data access layers
are all about removing that functionality from the domain, which is specifically what we do not
want to do. DAO's only came into being because of the shortcomings of the EJB spec.
Nobody uses Entity EJB's anymore, so please stop using DAO's.
DDD on 3 tiers (Differents JVM)
Jun 29, 2008 08:28 by iury ribeiro
Hi Srini,
Great discussion! I enjoyed a lot.
Page 25 of 32 Assembled by RunPDF.com
Reply Back to top
I would like to clarify the following case:
As you said that the CRUD methods belong to entity objects(domain object)and to get the
others objects through the navigation, So I released in the case where the application is split
on 2 JVM accessing a stateless session bean, We need to convert ours POJO on Proxy Pojo
to access the facede session.
Am I right?
Regards,
Iury
Reply Back to top
Sculptor
Jul 01, 2008 02:20 by Patrik Nordwall
Nice article! Looking for a tool that supports this type of design? Take a look at Sculptor...
Sculptor is an Open Source tool that applies the concepts from Domain-Driven Design and
Domain Specific Languages.
You express your design intent in a textual specification, from which Sculptor generates high
quality Java code and configuration. Sculptor takes care of the technical details, the tedious
repetitive work, and let you focus on delivering more business value – and have more fun.
The generated code is based on well-known frameworks, such as Spring Framework, Spring
Web Flow, JSF, Hibernate and Java EE.
The DSL and the code generation drives the development and is not a one time shot. It is an
iterative process, which can be combined with Test Driven Development and evolutionary
design.
Sculptor home: fornax-platform.org/cp/x/aAQ
Reply Back to top
Re: It's wonderful!
Jul 01, 2008 10:09 by iury ribeiro
Hello Lindsay,
May you clarify my question?
In the following case: where the application is split on 2 (tomcat and jee server) JVM
accessing a stateless session bean, We need to convert ours POJO on Proxy to access the
facade session. Am I right?
Re: It's wonderful!
Page 26 of 32 Assembled by RunPDF.com
Reply Back to top
Jul 02, 2008 08:38 by Lindsay Holman
Hi Iury,
I'm not entirely clear on exactly what it is you need to do, but I'll take a guess and put
something forward.
Typically, our front end will call a SLSB Facade on tier 2. The traditional, and still somewhat
sensible way of doing this is implementing an application service via the SLSB. If for instance
we want to get a Loan object, tier 1 would call the tier 2 SLSB application service. The
application service would have access to the domain model, querying the LoanRepository to
find the required Loan object and passing it back.
This type of arrangement allows you to incorporate an SOA implementation alongside the rich
domain model. The SLSBs can be thought of as gateways to the model.
Reply Back to top
Re: DDD on 3 tiers (Differents JVM)
Jul 03, 2008 03:30 by Srini Penchikala
Hi Iury, Sorry for the delayed reply. DDD design and development concepts remain valid even
if you are architecting your application as a 2-tier or multi-tier application. Domain objects live
(at run-time) behind the facade layer (implemented using stateless session beans or POJO's).
One thing to keep in mind (if you have a choice) is to work on the domain layer first to capture
the business logic, business rules, persistence etc first and then work on the facade classes
which should be just proxy classes to the domain layer (i.e. they shouldn't have business
logic, only the orchestrate type of logic).
Reply Back to top
Re: Sculptor
Jul 03, 2008 05:52 by Srini Penchikala
Hi Patrik, Thanks for info on Sculptor. It looks very interesting. I am currently working on a
research project on DDD and Code Generation topic and I have been looking
OpenArchitectureWare tool for code generation and MDA purposes. Sculptor has Hibernate
and Spring integration which is very coo. I will read about it in more detail and check with you
if I have any questions.
Reply Back to top
Re: It's wonderful!
Jul 04, 2008 05:44 by Mattias Fagerström
Can you explain the difference between an entity object and a domain object?
Reply Back to top
Re: It's wonderful!
Jul 08, 2008 06:31 by Srini Penchikala
Hi Mattias, Entity object is a type of domain object (Value Object, Service, Repository etc
being the other types). I use the terms and definitions covered in Eric Evans' book Domain
Driven Design.
Naming throwing
Jul 08, 2008 06:45 by Eduardo Miranda
I got confuse if the idea was give a real example of DDD or just throw all the tools and
Page 27 of 32 Assembled by RunPDF.com
Reply Back to top
practices names.
Do you really need all these tools to develop a DDD application?
Reply Back to top
Re: I *completely* agree
Jul 09, 2008 06:12 by Dimitris Menounos
The article declares the anemic model as an anti-pattern (is it really?) but then, if you look at
the source, implements the "rich domain objects" as Entities + embedded DAOs.
Reply Back to top
Re: Naming throwing
Jul 13, 2008 07:26 by Srini Penchikala
Hi Eduardo, It's not the intention of this article to suggest that every business domain out
there in the real world requires all the tools and techniques mentioned in the article. If OOP by
itself can represent a business domain and support DDD adequately then no other tools are
needed for implementing such a domain. But after working on few domain implementation
projects (of various sizes and scopes), I found that other techniques such as DI and AOP can
complement OOP in addressing the business domain requirements especially in terms of
persistence, transaction management and application security. If you could share your
thoughts and experiences on what tools you used in implementing domain driven design
projects, that would be great.
Reply Back to top
Re: I *completely* agree
Jul 13, 2008 07:33 by Srini Penchikala
Hi Dimitris, From my experience after working on few J2EE projects involving different sizes of
business domains, I found that anemic model is an anti-pattern to DDD implementation. Most
of J2EE developers are still designing the applications with a stateless session bean (facade)
that has all the business logic and leaving the domain objects (Entities) with just
getters/setters. Can you elaborate more on why you think anemic model is not an anti-
pattern? I am thinking may be there are some use cases where anemic model makes sense,
but I am curious know more about those use cases. Regarding the sample application, I spent
more time in focusing on how to use DI and AOP in a DDD application. You are right, in a
real-world DDD application, Entities which should have lot more business logic and domain
state manipulation logic than what's included in the code examples.
What about the Grails approach?
Aug 03, 2008 07:21 by Goran Oberg
Thanks for a good article. I have used JPA and the standard DAO approach in a couple of
projects (not DDD but still an OK approach), but I'm now involved a Grails based project and
that have definitely made me to take a more serious interest in DDD.
What I like about Grails and more specifically the GORM, is the domain centric approach to
data access. No daos and no repositories to be implemented, just plain domain classes! A
dynamic language like Groovy giving the possibility to constructs like
User.findAllByNameAndTimeBetween(name,start,end) without implementing the finder method
(dynamically created), just adds to the plus side.
Of course Grails have downsides as well (some of them quite serious to), but it will not stop
Page 28 of 32 Assembled by RunPDF.com
Reply Back to top
me from using Grails on certain projects and it will definitely give me some architectural
inspiration when I'm back on my next Spring-hibernate project.
Just a small comment on the source code in the article:
Shouldn't finder related methods be static and operations like save act on the object it self?
Reply Back to top
Re: What about the Grails approach?
Sep 04, 2008 10:22 by Soner Dastan
Hi Srini. First of all thanks for this good article.
I read several articles about DDD but still I could not find out, when to use the DDD approach
makes sense and why the "anemic" principle is an anti-pattern. I can not see that using the
anemic model causes issues to call it an anti-pattern.
In the anemic model we also have the separation of responsibilities and so on.
What are the differences except that the domain model in case of DDD includes business
logic?
Both models has a similar architecture layering.
Is there an article comparing both approaches with their pro and contras and showing sample
use cases where which design style should be used?
Reply Back to top
Re: What about the Grails approach?
Sep 27, 2008 11:54 by Srini Penchikala
Hi Soner, Thanks for the comments on the article. The main principle that I learned from using
DDD in my projects is that Domain comes first and Infrastructure comes second. With this
philosophy, I have seen a big difference in how I and other developers approach the design
and coding tasks. Regarding the resources for DDD, the best place is to start is Domain
Driven Design website. Also, feel free to post this question on DDD yahoo group which is a
great forum to discuss DDD related questions and ideas.
Reply Back to top
DDD and agile
Oct 06, 2008 08:29 by Nima n
agile methodology use user story for gathering requirement, what is user story role in domain
driven design?
Reply Back to top
Re: DDD and agile
Oct 21, 2008 09:56 by Srini Penchikala
Hi Nima, Agile methodologies is a better fit for DDD implementation in the sense that Agile
methodologies encourage iterative and incremental development. Modeling, design,
development, and unit testing phases in a DDD project are best done using the Agile and
Iterative approach.
Domain objects should not call CURD operations
Sep 28, 2009 06:04 by Sandeep akhare
Page 29 of 32 Assembled by RunPDF.com
Reply Back to top
Hi Srini,
Article's starting was good and even i sent this link to my friends saying great implementation
for DDD. But when we saw the code in the domain entities method you are calling CURD
operation which smells some wrong implementation. You are neglecting basic rule of domain
driven design which says that your domain should be persistance ignorent.
Please let me know if my understanding is wrong. What should is say to my friends whome i
sent this link .
Reply Back to top
Re: Mixed feelings
Oct 26, 2009 04:40 by H S
Srini,
First thanks a lot for good article. I followed through your article and reviews of different
people.
I still have one question (as Lindsay said) and you also agreed that persistence should be the
responsibility of the repository rather than the entity. We need one domain object which would
be acting as a (service) creating a entity and persisting the entity to DB.
e.g
Loan newLoan = CreateLoanWithBusinessRequirements()
loanRepository.save(newLoan)
Which domain object will you add this kind of behavior, and do we require such domain object
for each entity in our domain?
Reply Back to top
don't inject repository into model
Jan 19, 2010 08:53 by Peng Sunny
the sample is not perfect, don't inject any technology into business model, decouple "What"
from "How". we can use Domain Events pattern to do communication with them. all these have
implemented in my famework(DDD framework for Java) jdon.dev.java.net
Reply Back to top
Re: Not even close to DDD
May 03, 2010 04:30 by 李 引
eclipse aspectj can worked in osgi style.
Reply Back to top
Domain Layer uses the Infrastructure Layer. The layer below it.
May 19, 2010 08:38 by Roy Oliver
I am highly confused by the implementations I'm seeing all over the net. Recall this?
www.herrodius.com/blog/wp-content/uploads/2010/... - Eric's Layered Architecture? The
domain layer uses the infrastructure layer and has the ability to inherit objects from it. Not the
other way around. Did I read it wrong? Why are projects referencing the domain layer from
the infrastructure layer? That seems to be a direct violation of DDD.
Could some of you attempt to explain this?
I'm seriously confused.
A comment on the sample application
Apr 23, 2012 11:08 by Enrique Molinari
Page 30 of 32 Assembled by RunPDF.com
Development
Technical Practices as a Hackon Consciousness: Why toHack Yourself
Continuous Deployment atCoolblue
DevOps Enterprise Adoption atITV with Tom Clark
Architecture & Design
Technical Practices as a Hackon Consciousness: Why toHack Yourself
Stormpath's Java SDK 1.0Released
12 Factor, or Cloud Native Apps- What Exactly Does that Meanfor Spring Developers?
Culture & Methods
Technical Practices as a Hackon Consciousness: Why toHack Yourself
Continuous Deployment atCoolblue
The Platform Manifesto
Data Science
Google Launches CloudNatural Language API
Chris Fregly on the PANCAKESTACK Workshop and DataPipelines
Machine Learning Fast andSlow
DevOps
DevOps Enterprise Adoption atITV with Tom Clark
Stormpath's Java SDK 1.0Released
Amazon Simple NotificationService (SNS) GainsWorldwide SMS Delivery
Home QCONS WORLDWIDE
Reply Back to top
I found DDD interesting, but I also think that Object Oriented Programming is DDD by
definition. And with this in mind, I don't understand why the domain objects in the sample
application are full of getters and setters and without any interesting behaviour. Probably the
implemented requirements are too simple and that does not help to create a rich object model
? The process loan funding might have an interesting business logic that, from my
understanding, should be modeled in your domain objects, rather than in a service method. I
have posted an example related with object oriented design here:
www.copypasteisforword.com/notes/object-oriente....
Reply Back to top
Re: It's wonderful!
Jul 25, 2012 01:11 by Felipe Guarneri
Great!
Reply Back to top
Very bad example application, practically anti-DDD example
Sep 27, 2012 05:07 by Georgi Danov
I was going to read the article, but colleague showed me the sample application first. The
sample application is total s**t and has nothing to do with DDD so I am totally not going to
waste my time reading the article. Read the book man...
Reply Back to top
Re: Very bad example application, practically anti-DDD example
Jan 06, 2013 02:02 by Roman Tmk
When saying that something is not good, you should point out what exactly you disagree with,
otherwise your comment has no meaning.
Reply Back to top
DDD Modeling tool set
Oct 09, 2015 11:09 by becky cortino
Is there a specific modeling/mapping tool to use for domain driven design? Preferably free.
Page 31 of 32 Assembled by RunPDF.com
All topics
QCon Conferences
About InfoQ
Our Audience
Contribute
About C4Media
Create account
Login
ShanghaiOct 20-22, 2016
San FranciscoNov 7-11, 2016
Tokyo 2016
LondonMar 6-10, 2017
BeijingApr 16-18, 2017
São PauloApr 24-26, 2017
New YorkJun 26-30, 2017
Your personalized RSS
For daily content and announcements
For major community updates
For weekly community updates
Personalize Your Main Interests
Development
Architecture & Design
Data Science
Culture & Methods
DevOps
This affects what content you see on thehomepage & your RSS feed. Clickpreferences to access more fine-grainedpersonalization.
General [email protected]
InfoQ.com and all content copyright © 2006-2016C4Media Inc. InfoQ.com hosted at Contegix, the bestISP we've ever worked with.Privacy policy
InfoQ Weekly Newsletter
Subscribe to our Weekly email
newsletter to follow all new
content on InfoQ
Your email here SubscribeSubscribe
Your browser (Apple Safari 5) is out of date. infoq.com recommends to update your browser for more security, comfort and the best experience on this site. x
Page 32 of 32 Assembled by RunPDF.com
FEBRUARY 2009
Best Practice ‐ An Introduction ToDomain‐Driven DesignBy David Laribee | February 2009
This article discusses:
Modeling from Ubiquitous Language
Bounded Contexts and aggregate roots
Using the Single Responsibility Principle
Repositories and databases
This article uses the following technologies: Visual Studio
Contents
The Platonic Model Talk the Talk Context Know Your Value Proposition A System of Single Responsibilities Entities Have an Identity and a Life Value Objects Describe Things Aggregate Roots Combine Entities Domain Services Model Primary Operations Repositories Save and Dispense Aggregate Roots The Thing with Databases Getting Started with DDD
Domain‐Driven Design﴾DDD﴿ is a collection of principles and patterns that helpdevelopers craft elegant object systems. Properly applied it can lead tosoftware abstractions called domain models. These models encapsulatecomplex business logic, closing the gap between business reality and code.
In this article, I'll cover the basic concepts and design patterns germane toDDD. Think of this article as a gentle introduction to designing and evolvingrich domain models. To provide some context to the discussion, I'm using acomplex business domain with which I'm familiar: insurance policymanagement.
If the ideas presented here appeal to you, I highly recommend that youdeepen your toolbox by reading the book Domain‐Driven Design: TacklingComplexity in the Heart of Software, by Eric Evans. More than simply theoriginal introduction to DDD, it is a treasure trove of information by one ofthe industry's most seasoned software designers. The patterns and coretenets of DDD that I will discuss in this article are derived from the conceptsthat are detailed in this book.
VOLUME 24 NUMBER 02
Issues and downloads / 2009 / February 2009 / Best Practice: An Introduction To Domain‐Driven Design
Sign in MSDN subscriptions Get toolsDeveloper Network
magazine
Issues and downloads Subscribe Submit article
Page 1 of 14 Assembled by RunPDF.com
Cutting Contexts by Architectural NeedBounded Contexts needn't be organized solely by the functional areaof an application. They're very useful in dividing a system to achievedesired architectural examples. The classic example of this approachis an application that has both a robust transactional footprint and aportfolio of reports.
It's often desirable in such circumstances ﴾which might occur prettyoften﴿ to break out the reporting database from the transactionaldatabase. You want the freedom to pursue the right degree ofnormalization for developing reliable reports, and you want to use anObject‐Relational Mapper so that you can keep coding transactionalbusiness logic in the object‐oriented paradigm. You can use atechnology such as Microsoft Message Queue ﴾MSMQ﴿ to publishdata updates coming from the model and incorporate them intodata warehouses optimized for reporting and analysis purposes.
This might come as a shock to some, but it's possible for databaseadministrators and developers to get along. Bounded Contexts giveyou a glimpse of this promised land. If you're interested inarchitectural Bounded Contexts, I highly recommend keeping tabs onGreg Young's blog. He's quite experienced with and articulate aboutthis approach and produces a fair amount of content on the subject.
The Platonic Model
Since we're just starting off here, it makes practical sense to define what Imean by model. Answering this question leads us on a short, metaphysicaljourney. Who better than Plato to guide us?
Plato, that most famous student of Socrates, proposed that the concepts,people, places, and things we intuit and perceive with our senses are merelyshadows of the truth. He dubbed this idea of a true thing a Form.
To explain Forms, Plato used what's become known as the allegory of thecave. In this allegory, there exists a people that are bound inside a deep, darkcave. These cave people are chained in such a way that they can only ever seea blank wall of the cave that receives light from the opening. When an animalwalks by the opening, a shadow is projected onto the interior wall that thecave dwellers see. To the cave dwellers, these shadows are the real thing.When a lion walks by, they point at the shadow of the lion and exclaim, "Runfor cover!" But it is really only a shadow of the real Form, the lion itself.
You can relate Plato's theory of Forms to DDD. Much of its guidance helps usget closer to the ideal model over time. The path to the Form you want todescribe with your code is scattered about in the minds of domain experts,the desires of stakeholders, and the requirements of industries in which we'reworking. These are, in a very real sense, the shadows to Plato's imaginary cavedwellers.
Furthermore, you are often constrained by programming languages andconsiderations of time and budget in trying to reach that Form. It's not muchof a stretch to say these limitations are the equivalent of cave dwellers onlyever being able to see the interior wall of shadows.
Good models exhibit a number of attributes independent of theirimplementation. The fact of the matter is, the mismatch between the modelthat's in everyone's head and the model you're committing to code is the first
Page 2 of 14 Assembled by RunPDF.com
thing an aspiring domain modeler should understand.
The software you create is not the true model. It is only a manifestation—ashadow, if you will—of the application Form you set out to achieve. Eventhough it's an imitation of the perfect solution, you can seek to bring thatcode closer to the true Form over time.
In DDD, this notion is called model‐driven design. Your understanding of themodel is evolved in your code. Domain‐driven designers would rather notbother with reams of documentation or heavy diagramming tools. They seek,instead, to imbue their sense of domain understanding directly into theircode.
The idea of the code capturing the model is core to DDD. By keeping yoursoftware focused on the problem at hand and constrained to solving thatproblem, you end up with software receptive to new insights and moments ofenlightenment. I like what Eric Evans calls it: crunching knowledge intomodels. When you learn something important about the domain, you'll knowright where to go.
Talk the Talk
Let's examine some of the techniques DDD provides for achieving this goal. Abig part of your job as a developer is working with non‐coders to understandwhat you're meant to deliver. If you're working in an organization with anykind of process, you likely have requirements expressed as a user story, task,or use case. Whatever kind of requirements or specification you receive, is itusually complete?
Typically requirements are somewhat murky or expressed at a high level ofunderstanding. In the course of designing and implementing a solution, it'sbeneficial when developers have access to the people who bring someexpertise in the intended domain. This is exactly the point of user stories,which are typically expressed according to a template like this: as a [role], Iwant [feature] so that [benefit].
Let's take one example from the domain of insurance policy management: asan underwriter, I want approval control over a policy so that I can write safeexposures and reject risky ones.
Is there anyone who understands what that means? I know I didn't when I sawit written and prioritized. How can you possibly understand everything thatwill need to go into delivering the supporting software from this abstracteddescription?
User stories, properly done, are an invitation to have a conversation with theirauthor—the user. This means when you go to work on the approve/denypolicy feature, you should ideally have access to an underwriter. Underwriters,for the uninitiated, are domain experts ﴾at least good ones are﴿ who determinewhether a certain category of exposure is safe for a carrier to cover.
When you begin discussing the feature with your underwriter ﴾or whomeveryour project domain expert might be﴿, pay especially close attention to theterminology the underwriter uses. These domain experts use company‐ orindustry‐standard terminology. In DDD, this vocabulary is called theUbiquitous Language. As developers, you want to understand this vocabularyand not only use it when speaking with domain experts but also see the sameterminology reflected in your code. If the terms "class code" or "rate sets" or"exposure" are frequently used in conversation, I would expect to findcorresponding class names in the code.
This is a pretty fundamental pattern to DDD. At first blush, the Ubiquitous
Page 3 of 14 Assembled by RunPDF.com
Language seems like an obvious thing, and chances are a good that numberof you are already practicing this intuitively. However, it is critical thatdevelopers use the business language in code consciously and as adisciplined rule. Doing so reduces the disconnect between businessvocabulary and technological jargon. The how becomes subordinate to thewhat, and you stay closer to the reason for your job: delivering businessvalue.
Context
Developers are, in a sense, organizers. You sling code ﴾hopefully with intent﴿into abstractions that solve problems. Tools such as design patterns, layeredarchitectures, and object‐oriented principles give a framework for applyingorder to evermore complicated systems.
DDD extends your organizational toolbox and borrows from well‐knownindustry patterns. What I like most about the organizational patterns thatDDD lays out is that there are solutions for every level of detail in a system.Bounded Contexts guide you toward thinking of software as a portfolio ofmodels. Modules help you organize a larger single model into smaller chunks.Later, I'll cover aggregate roots as a technique for organizing smallcollaborations between a few highly related classes.
In most enterprise systems there are course‐grained areas of responsibility.DDD calls this top level of organization a Bounded Context.
Workers' compensation insurance policies need to be concerned withelements such as:
Quoting and salesGeneral policy workflow ﴾renewals, terminations﴿Auditing payroll estimationQuarterly self‐estimatesSetting and managing ratesIssuing commissions to agencies and brokersBilling customersGeneral accountingDetermining acceptable exposures ﴾underwriting﴿
Wow. That's a lot of stuff! You could incorporate all of this into a single,monolithic system, but doing so leads you down a foggy, amorphous path.People are talking about two entirely different things when they chat about apolicy in the context of a general workflow versus a policy in the context ofpayroll auditing. If you use the same policy class, you're fattening the profileof that class and getting a long way from tried‐and‐true best practices suchas the Single Responsibility Principle ﴾SRP﴿.
Systems that fail to isolate and insulate Bounded Contexts often slip into anarchitectural style ﴾amusingly﴿ called The Big Ball of Mud. In 1999, Brian Footand Joseph Yoder defined the architectural style ﴾or anti‐architectural style, asthe case may be﴿ in their classic paper of the same name ﴾" Big Ball of Mud"﴿.
DDD nudges you toward identifying contexts and constraining your modelingeffort within particular contexts. You can use a simple diagram, called acontext map, to explore the boundaries of our system. I've enumerated thecontexts involved in a fully featured, insurance policy management system,and Figure 1takes this from a textual description to a ﴾partial﴿ graphicalcontext map.
Did you notice some key
Page 4 of 14 Assembled by RunPDF.com
Figure 1 From Bounded Context to Context Map
relationships among thevarious BoundedContexts? This is valuableintelligence because youcan start makinginformed business andarchitectural decisionssuch as packaging anddeployment design;choice of technologyused to marshalmessages betweenmodels; and, perhapsmost important, where
you choose to set milestones and deploy effort, time, and talent.
One last but very important thought about Bounded Contexts: each contextowns its own Ubiquitous Language. It's important to differentiate between thenotion of a policy in the auditing subsystem versus the policy in coreworkflow because they're different things. While they may have the sameidentity, the value objects and child entities ﴾more on these in a bit﴿ are oftenradically different. Since you're modeling within context, you also want thelanguage to provide precision within that context so you can have productivecommunication with domain experts and within your teams.
Some areas inside models group more closely together than others. Modulesare a means of organizing these groups within a particular context, serving asmini‐boundaries where you want to stop and think about associations toother modules. They are also another organization technique that leads youaway from "Small Balls of Mud." Technologically, modules are easy to create;in the Microsoft .NET Framework they are simply namespaces. But the art ofidentifying modules involves spending a little time with your code. Eventuallyyou may see a few things emerge as a mini‐model within a model, at whichtime you may consider dividing things into namespaces.
Teasing apart models into cohesive modules has a nice effect in your IDE.Namely, since you need to use multiple using statements to include modulesexplicitly, you get a much cleaner IntelliSense experience. They also give you away of looking at associations between larger conceptual chunks of yoursystem with a static analysis tool such as NDepend.
Introducing an organizational change to your model should prompt you toengage in some pragmatic, cost‐benefit thinking. When you use modules ﴾ornamespaces﴿ to divide up your model, you really want to question whetheryou're dealing with a separate context. The cost of cleaving out anothercontext is usually much higher: now you have two models, likely in twoassemblies, that you need to connect with application services, controllers,and so on.
Anti‐Corruption LayersAn Anti‐Corruption Layer ﴾ACL﴿ is another DDD pattern thatencourages you to create gatekeepers that work to prevent non‐domain concepts from leaking into your model. They keep themodel clean.
At their heart, repositories are actually a type of ACL. They keep SQLor object‐relational mapping ﴾ORM﴿ constructs outside of your
Page 5 of 14 Assembled by RunPDF.com
model.
ACLs are a great technique for introducing what Michael Featherscalls, in his book Working Effectively With Legacy Code, a seam. Aseam is an area where you can start to cleave off some legacy codeand begin to introduce changes.Finding seams, along with isolatingyour core domain, can be extremely valuable when using DDDtechniques to refactor and tighten the highest value parts of yourcode.
Know Your Value Proposition
Most development shops have a handful of both seasoned businesspeopleand top developers who are capable of isolating and describing a problemand building an elegant, maintainable object‐oriented solution. To get thebiggest bang for your customer's buck, you want to be sure to understandthe core domain of your application. The core domain is the Bounded Contextthat brings the most value to applying DDD.
In any given enterprise system, there are some areas that are more importantthan others. The more important areas tend to fall into alignment with thecore competencies of the client. It's rare that a business will be runningcustom general ledger software. But if that business is in insurance ﴾goingwith my previous example﴿ and their money‐making offering is managing riskpools where liability is spread among all members, then they had better bedarned good at rejecting bad risks and identifying trends. Or perhaps youhave a client that's a medical claims processor, and their strategy is to flanktheir competition on pricing by automating payments to amplify the effortsof their bill payor workforce.
Whatever the industry, your employer or client has some edge in the market,and this edge is usually where you find the custom software. That customsoftware is where you're likely to find and model the core domain.
We can measure our investment in value on another dimension, namely wherewe invest our intellectual capital in reaching technical excellence. Too manytimes senior developers are the kind of people who get obsessed with newtechnologies. A certain amount of this is to be expected—the industryinnovates at a relentless pace, and vendors are compelled to frequentlyrelease new technology offerings to satisfy their customers' demands andstay competitive. The challenge, as I see it, is for senior developers to masterthe fundamental principles and patterns that contribute value to the heart of asystem. It's tempting to get wrapped up in a new framework or platform, butwe need to remember the reason vendors produce these things is so we canjust trust that they work.
A System of Single Responsibilities
I've mentioned that DDD provides a pattern language for structuring richdomain models. By implementing these patterns, you get a certain level ofadherence to the SRP for free, and that's certainly valuable.
The SRP encourages getting at the core purpose of an interface or class. Itguides you toward high cohesion—a very good thing, as it makes code easierto discover, reuse, and maintain.
DDD identifies certain types of class responsibilities in a core collection ofpatterns. I'll cover a few of the more primary ones now, but it's worthmentioning that there are many patterns described by Eric Evans in the
Page 6 of 14 Assembled by RunPDF.com
original book ranging from class level to architectural. For introductorypurposes, I'll stay at the class level covering entities, value objects, aggregateroots, domain services, and repositories. Because this is an introduction, I'llonly cover the responsibility of each pattern with one to two code examplesor tips each.
Entities Have an Identity and a Life
An entity is a "thing" in your system. It's often helpful to think about these interms of nouns: people, places, and, well, things.
Entities have both an identity and a lifecycle. For example, If I want to access aparticular customer in my system, I can ask for her by a number. When Icomplete a trading order, it's then dead to my system and can go to long‐term storage ﴾the historical reporting system﴿.
Think of entities as units of behavior rather than as units of data. Try to putyour logic in the entities that own them. Most times there's an entity thatshould receive some operation you're trying to add to your model, or a newentity is begging to be created or extracted. In more anemic code, you find alot of service or manager classes that validate entities from the outside. Ingeneral, I much prefer to do that from within the entity—you get all thebenefits associated with the fundamental principle of encapsulation, andyou're making your entities behavioral.
Some developers are bothered by having dependencies in their entities.Obviously you need to create associations between the various entities inyour system. For example, you might need to obtain a Product entity fromthe Policy entity so you can determine sensible defaults on the policy. Wherepeople seem to fall down is when you need some outside service to performbehavior intrinsic to an entity.
I, for one, am not disturbed by the need to involve other, non‐entity classes,and I would try to avoid lifting the central behavior outside of my entity. Youshould always remember that entities are intrinsically behavioral units. Oftenthat behavior will be implemented as a kind of state machine—when youinvoke a command on an entity, it is responsible for changing its internal state—but sometimes it's necessary for you to obtain additional data or imposeside‐effects upon the outside world. My preferred technique foraccomplishing this is to provide the dependency to the command method:
The benefit of this approach is that you don't need an inversion of control﴾IOC﴿ container to create an entity for you. Another perfectly acceptableapproach, in my opinion, would be to use a Service Locator to resolve theIAuditNotifier inside the method. This technique has the benefit of keepingthe interface clean, but I find the former strategy tells me a lot more about mydependencies at a higher level.
Value Objects Describe Things
Value objects are descriptors or properties important in the domain you are
public class Policy public void Renew(IAuditNotifier notifier) // do a bunch of internal state‐related things, // some validation, etc. ... // now notify the audit system that there's // a new policy period that needs auditing notifier.ScheduleAuditFor(this);
Page 7 of 14 Assembled by RunPDF.com
modeling. Unlike entities, they do not have an identity; they simply describethe things that do have identities. Are you changing an entity called "Thirty‐Five Dollars" or are you incrementing the balance of an account?
Part of the beauty of value objects is that they describe the properties ofentities in a much more elegant and intention‐revealing way. Money, acommon value object, looks a lot better as a function parameter on a fundstransfer API than a decimal does. When you spot it in an interface or entitymethod, you know what you're dealing with right away.
Value objects are immutable. They are incapable of change once they arecreated. Why is it important that they be immutable? With value objects,you're seeking side‐effect‐free functions, yet another concept borrowed byDDD. When you add $20 to $20, are you changing $20? No, you are creatinga new money descriptor of $40. In C# you can use the read‐only keyword onpublic fields to enforce immutability and side‐effect‐free functions, as shownin Figure 2.
Figure 2 Using Read‐Only to Enforce Immutability
Aggregate Roots Combine Entities
An aggregate root is a special kind of entity that consumers refer to directly.Identifying aggregate roots allows you to avoid over‐coupling the objectsthat comprise your model by imposing a few simple rules. You should notethat aggregate roots guard their sub‐entities zealously.
The biggest rule to keep in mind is that aggregate roots are the only kind ofentity to which your software may hold a reference. This helps avoid The BigBall of Mud because you now have a constraint that prevents you fromcreating a tightly coupled system where everything has an association toeverything else.
Let's assume I have an entity called Policy. Well, policies get renewed on anannual term, so there's likely an entity called Period. Since a Period cannotexist without a Policy and you can act on Periods through Policy, Policy is saidto be an aggregate root and Period is a child of the same.
I like my aggregate roots to just figure it out for me. Consider this consumercode accessing a Policy aggregate root:
I'm trying to renew an insurance policy—recall the class diagram of the coredomain of insurance policy management. Note how I'm dotting my way tothe behavior I want to invoke?
public class Money public readonly Currency Currency; public readonly decimal
Policy.CurrentPeriod().Renew()
Page 8 of 14 Assembled by RunPDF.com
There are a couple of problems with this approach. First, I'm clearly violatingthe Law of Demeter. A method M of an object O should invoke only themethods of the following kinds of objects: itself, its parameters, any objects itcreates or instantiates, or its direct component objects.
Isn't deep dotting kind of convenient? IntelliSense is one of the coolest, mostuseful features of Visual Studio and other modern IDEs, but when you startdotting your way to the function you actually want to invoke, you'reintroducing unnecessary coupling into the system. In the previous example,I'm now dependent upon the Policy class and the Period class.
For further reading, Brad Appleton has an excellent article available on his sitethat explains the deeper implications, theories, tooling and caveats around theLaw of Demeter.
The cliche "death by a thousand cuts" is a good description of the potentialmaintenance nightmare of an overly coupled system. When you createunnecessary references all over the place, you also create a rigid model wherechanges in one place result in a cascade of changes all over consumer code.You could accomplish the same goal with, as far as I'm concerned, a muchmore expressive bit of code:
See how the aggregate just figures it out? Internally it can find the currentperiod and whether or not there's already a renewal period and whatever elseyou need it to do.
I find that when I'm unit testing my aggregate roots using a technique such asBehavior‐Driven Development ﴾BDD﴿, my tests trend toward the more black‐box and state‐testing paradigm. Aggregate roots and entities often end up asstate machines, and the behavior matches accordingly. I end up with statevalidation, addition, and subtraction. There's quite a bit of behavior going onin the renewal example in Figure 3, and it's pretty clear how you can expressthis in a BDD style of test.
Figure 3 Testing Aggregate Roots
Domain Services Model Primary Operations
Sometimes you have operations or processes that do not have an identity orlifecycle in your domain. Domain services give you a tool for modeling theseconcepts. They're typically stateless and highly cohesive, often providing asingle public method and sometimes an overload for acting on sets.
Policy.Renew()
public class When_renewing_an_active_policy_that_needs_renewal Policy ThePolicy; DateTime OriginalEndingOn; [SetUp]
Page 9 of 14 Assembled by RunPDF.com
I like to use services for a few reasons. When there are a number ofdependencies involved in a behavior and I can't find a natural place on anentity to place that behavior, I'll use a service. When my Ubiquitous Languagetalks about a process or operation as a first‐order concept, I'll questionwhether a service makes sense as a central point of orchestration for themodel.
You could use a domain service in the case of renewal. This is an alternativestyle. Rather than method injecting an IAuditNotifier directly into the methodof the Policy entity's Renew method, you might choose to extract a domainservice to handle dependency resolution for us; it's more natural for us toresolve a domain service from an IOC container than an entity. This strategymakes a lot more sense to me when there are multiple dependencies, but I'llpresent the alternative anyway.
Here is a short example of a domain service:
The word service is a highly overloaded term in the developer world.Sometimes I think of service as in service‐oriented architecture ﴾SOA﴿. Othertimes I think of services as little classes that don't represent a particularperson, place, or thing in my application, but that tend to embody processes.Domain services usually fall in this latter category. They tend to be namedafter verbs or business activities that domain experts introduce into theUbiquitous Language.
Application services, on the other hand, are a great way to introduce a layeredarchitecture. They can be used for mapping data inside the domain model toa shape required by a client application. For example, maybe you need todisplay tabular data in a DataGrid, but you want to maintain a granular andjagged object graph in your model.
Application services are also quite useful for integrating multiple models—forexample, translating between policy auditing and core policy workflow.Similarly, I use them to bring infrastructure dependencies into the mix.Imagine a common scenario where you want to expose your domain modelwith Windows Communication Foundation ﴾WCF﴿. I'd use an applicationservice decorated with the WCF attributes to make this happen rather thanletting WCF leak into my pure domain model.
Application services tend to be very broad and shallow, embodying cohesivefunctionality. Consider the interface and partial implementation you see in thecode in Figure 4as a good example of an application service.
Figure 4 A Simple Application Service
public class PolicyRenewalProcesor private readonly IAuditNotifier _notifier;
public IPolicyService void Renew(PolicyRenewalDTO renewal); void Terminate(PolicyTerminationDTO termination);
Page 10 of 14 Assembled by RunPDF.com
Repositories Save and Dispense Aggregate Roots
Where do you go to retrieve entities? How do you store them? Thesequestions are answered by the Repository pattern. Repositories represent anin‐memory collection, and the conventional wisdom is that you end up withone repository per aggregate root.
Repositories are a good candidate for a super class or what Martin Fowlerrefers to as the Layer Supertype pattern. Using generics to derive a baserepository interface from the previous example is a simple matter:
Repositories prevent database or persistence concepts, such as SQLstatements or stored procedures, from commingling with your model anddistracting you from the mission at hand: capturing the domain. Thisseparation of model code from infrastructure is a good attribute. See thesidebar "Anti‐Corruption Layers" for a more detailed discussion.
At this point, you have likely noticed that I am not talking about howaggregate roots, their subordinate entities, and the attached value objectsactually get persisted to disk. This is intentional. Saving the data required toperform behavior in your model is a concern orthogonal to the model itself.Persistence is infrastructure.
A survey of these technologies is far beyond the scope of an introduction toDDD. Suffice it to say there are a number of suitable and mature options forstoring your model's data from Object‐Relational Mapping ﴾ORM﴿frameworks to document‐oriented databases to "roll‐your‐own" datamappers for simple scenarios.
DDD Resources
Dan North on How to Structure User Stories
The Big Ball of Mud Architectural Style
Robert C. Martin's Paper on Single Responsibility Principle
Brad Appleton on Law of Demeter
Martin Fowler Describes the Layer Supertype Pattern
Robert C. Martin on the S.O.L.I.D. Principles
The Thing with Databases
By this point, I'm sure you've thought, "This is all well and good, Dave. Butwhere do I save my entities?" Yes, you have to deal with this important detail,but how or where you persist your models is mostly tangential to an overviewof DDD.
A number of developers or database admins will make the assertion that the
public interface IRepository<T> where T : IEntity Find<T>(int id); Find<T>(Query<T> query); Save(T entity); Delete(T entity);
Page 11 of 14 Assembled by RunPDF.com
database is the model. In a lot of cases, that's partially true. Databases, whenhighly normalized and visualized with a diagramming tool, can convey a lotabout the information and relationships in your domain.
Data modeling as a primary technique leaves something to be desired,however. When you want to understand the behaviors inherent in the samedomain, data‐only techniques such as entity‐relationship diagrams ﴾ERDs﴿ orentity‐relationship models and class diagrams break down. You need to seethe application's parts in motion and how types collaborate to get work done.
When I am modeling, I often reach for sequence diagrams on a whiteboard asa communications tool. This approach captures much of the essence ofcommunicating a behavioral design or problem without the ceremony ofUnified Modeling Language ﴾UML﴿ or model‐driven architecture. I like to avoidunnecessary ceremony, especially when I'm going to erase the diagrams I puton the whiteboard. I don't worry about 100% UML adherence in my diagrams,preferring simple boxes, arrows, and swim lanes that I can sketch quickly.
If you don't already use sequence diagrams on your team, I highlyrecommend learning the technique. I've observed the powerful effect theyhave on getting team members to think through issues around the SRP,layered architecture, behavior design over data modeling, and architecturalthinking in general.
Getting Started with DDD
Becoming proficient with object‐oriented programming is no trivialundertaking. I believe competence is within the reach of most professionaldevelopers, but it takes dedication, book learning, and practice, practice, andmore practice. It also helps if you adopt an attitude of craftsmanship andcontinual learning.
How do you get started? Simply put: do your homework. Learn about thingslike the S.O.L.I.D. principles and study Eric Evans' book. Your time investmentwill more than make up for itself. InfoQ has produced a smaller version of theDDD book that introduces a few key concepts. If you're on a financial ortemporal budget or simply in investigation mode, I recommend startingthere. Once you get a solid footing, wander over to the Yahoo! DDD group tosee what issues your fellow designers are struggling with and get involved inthe conversation.
DDD is not a new doctrine or methodology. It's a collection of time‐testedstrategies. When you get ready to practice, try adapting those philosophies,techniques, and patterns that make the most sense in your situation. Someelements of DDD apply more universally than others. Understanding thereason for your core domain's existence by uncovering and using theUbiquitous Language and identifying the contexts in which we're modelingare way more important than nailing that perfectly opaque and one‐size‐fits‐all repository.
When you're designing your solutions, design for value. If designers produceart and developers are a kind of designer, then our medium has to bebusiness value. Value consciousness trumps considerations such as adherenceto dogma and choice of persistence technology, as important as thesechoices sometimes seem.
Dave Laribee coaches the product development team at VersionOne. He is a frequent speaker at
local and national developer events and was awarded a Microsoft Architecture MVP for 2007 and
Page 12 of 14 Assembled by RunPDF.com
2008.
MSDN Magazine Blog14 Top Features of Visual Basic 14: The Q&AWednesday, Jan 7Big Start to the New Year at MSDN MagazineFriday, Jan 2
More MSDN Magazine Blog entries >
Current Issue
Page 13 of 14 Assembled by RunPDF.com
Browse All MSDN Magazines
Subscribe to MSDN Flash newsletter
Receive the MSDN Flash e‐mail newsletterevery other week, with news and informationpersonalized to your interests and areas offocus.
Dev centers
Windows
Office
Visual Studio
Microsoft Azure
More...
Learning resources
Microsoft Virtual Academy
Channel 9
MSDN Magazine
Community
Forums
Blogs
Codeplex
Support
Self support
Programs
BizSpark ﴾for startups﴿
DreamSpark
Imagine Cup
United States ﴾English﴿ Newsletter Privacy & cookies Terms of use Trademarks
© 2016 Microsoft
Page 14 of 14 Assembled by RunPDF.com