This link has been bookmarked by 197 people . It was first bookmarked on 13 Jun 2008, by morphis ff.
-
17 Mar 16
-
06 Mar 16
-
Domain Driven Design (DDD) is about mapping business domain concepts into software artifacts.
-
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.
-
from a practical stand-point
-
and when to use a domain model in an enterprise (versus not using a domain model at all or using an anemic domain model).
-
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.
-
"Fat Service Layer" and an "Anemic Domain Model"
-
where facade classes (usually Stateless Session Beans) start accumulating more and more business logic
-
This approach also leads to domain specific business logic and rules being scattered (and duplicated in some cases) in several different facade classes.
-
implementing business requirement changes in this architecture take too long to develop and deploy to production environment.
-
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.
-
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).
-
The domain classes should be unit testable outside the container
-
Model and document business processes first.
-
Identify and document the state and behavior of the objects used by services identified in the previous step.
-
focus on the delivery of business value
-
just like DDD focuses on the alignment of software system with business model
-
Using SCRUM (for project management) and XP (for software development purposes)
-
Domain driven design effort begins where domain modeling ends
-
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.
-
Responsible for presenting information to the user and interpreting user commands.
-
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.
-
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.
-
validation
-
basic
-
doesn't contain any business or domain related logic or data access logic.
-
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.
-
DI facilitates a cleaner and loosely coupled design by injecting the other objects such as Repositories and Services into Domain Objects.
-
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
-
A recent trend to define and manage Aspects and DI is to use Annotations.
-
We should take advantage of annotations to generate the boiler plate code
-
In domain and service classes, authorization is managed at the class method invocation level.
-
- Data validation
- Data transformation
- Business decision-making
- Process routing (work-flow logic)
Business rules typically fall into the following categories:
-
The context is very important in DDD world.
-
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
-
A better design option is to put the rules where they belong,
-
inside the domain objects.
-
Domain elements should be designed to hold the domain state and behavior correctly.
-
Domain Element State/Behavior Entity, Value Object, Aggregate State 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
-
Also, the public constructors should contain only the required fields instead of a constructor with all the fields in the domain class.
-
DTO Assembler
-
the methods in a class are far too interested in data belonging to other classes.
-
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)
-
Some developers prefer managing the transactions in the DAO classes which is a poor design.
-
Service classes should handle transactions;
-
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.
-
Dozer framework is used for the assembly of one or more domain objects into a DTO object
-
-
19 Feb 16
-
20 Dec 15
-
16 Nov 15
-
04 Oct 15
-
21 Aug 15
-
25 Jun 15
-
01 Jun 15
-
14 Apr 15
-
04 Mar 15
-
21 Feb 15
-
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
-
Spring, Dozer, Spring Security, JAXB, Arid POJOs and Spring Dynamic Modules
-
create a common mode
-
the design reflects the business model
-
modular, extensible and easy to maintain
-
reusability and testability
-
Anemic Domain Model
-
Fat Service Layer
-
domain objects become mere data carriers
-
without any technology or framework dependencies
-
The domain model should be independent of persistence implementation details
-
we don't want any tight coupling on any external framework
-
commit to the investment
-
SOA design will become relatively simple by providing a shell (proxy) to the domain objects
-
brittle SOA architecture
-
agile methodologies focus on the delivery of business value
-
DDD focuses on the alignment of software system with business model
-
Domain driven design effort begins where domain modeling ends
-
domain entities
-
domain logic
-
only add services where the logic doesn't belong in any domain entity or value object
-
Application Layer
-
Domain Layer
-
Infrastructure Layer
-
navigation between the UI screens
-
non-business related
-
validation
-
can manage the state of the user session or the progress of a task
-
business use case
-
business rules
-
the heart of the business application
-
OOP is the most important element in the domain implementation
-
domain state change tracking, auditing, caching, transaction management
-
cross-cutting
-
makes DI a "must have" in DDD
-
to introduce data caching
-
annotations should be used with some caution
-
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.
-
The database layer is abstracted from domain layer in the form of an in-memory Object/Data Grid
-
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
-
it's a common practice to write (or code generate) DTO objects from the XSD's
-
Mapping the data from one or more domain objects to a DTO will become a necessary evil
-
Resources
-
-
01 Feb 15
-
30 Jan 15
-
21 Jan 15
-
Domain Driven Design
-
mapping business domain concepts into software artifacts
-
- Business Rules
- Persistence
- Caching
- Transaction Management
- Security
- Code Generation
- Test Driven Development
- Refactoring
influenced by several architectural, design, and implementation aspects such as:
-
application uses frameworks like Spring, Dozer, Spring Security
-
-
20 Jan 15
-
mapping
-
Domain Driven Design
-
business domain concept
-
software artifacts
-
taking a domain model
-
domain model
-
the domain model which is the representation of business entities
-
encapsulating the business logic and rules in domain objects
-
main ingredients of the current DDD implementation recipe
-
Domain objects
-
Plain Java Classes and Interfaces
-
Dependency Injection
-
out of
-
domain objects.
-
dependency code
-
to move
-
injecting the other objects such as Repositories and Services into
-
Domain Objects
-
Aspect Oriented Programming
-
removing
-
cross-cutting concerns code
-
from the domain objects
-
Annotations
-
Aspects and DI
-
define
-
manage
-
use Annotations
-
minimizing the required artifacts
-
simplify the configuration management tasks
-
take advantage of annotations to generate the boiler plate code where it adds value in terms of flexibility
-
Application security
-
only authorized clients
-
accessing the domain state
-
calling the domain operations
-
Business Rules
-
define data validation
-
need to be applied on domain objects
-
other constraints
-
context
-
the same domain object
-
process different set of business rules
-
different business context
-
-
10 Nov 14
-
11 Oct 14
-
01 Aug 14
-
25 Jun 14
-
17 May 14
-
28 Mar 14
-
24 Oct 13
-
16 Aug 13
-
11 Mar 13
-
23 Jan 13
-
09 Jan 13
-
30 Nov 12
-
26 Jul 12
-
16 Apr 12
-
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
-
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.
-
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.
-
-
17 Mar 12
-
21 Jan 12
-
- 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.
A typical enterprise application architecture consists of the following four conceptual layers:
-
- 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.
Let's look at the application and domain layers in more detail. The Application 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).
The domain layer:
-
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:
-
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.
-
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.
-
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 used to complement OOP to minimize tight coupling, enhance modularity and better manage the cross-cutting concerns.
-
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.
-
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).
-
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.
-
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.
-
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.
-
Security Concerns in Various Application Layers
Layer Security Concern Client/Controller Authentication, 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) -
- Data validation
- Data transformation
- Business decision-making
- Process routing (work-flow logic)
Business rules typically fall into the following categories:
-
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.
-
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
-
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
-
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 with state and behavior
Domain Element State/Behavior Entity, Value Object, Aggregate State and Behavior Data Transfer Object State only Service, Repository Behavior only -
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.
-
- 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.
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:
-
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.
-
A good design is to inject Repositories and Services into domain objects using DI & AOP techniques.
-
Persistence is an infrastructural aspect from which the domain layer should be decoupled
-
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.
-
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.
-
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.
-
- 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.
a typical use case involving the domain model. Following is the list of steps in the use case:
Request In:
-
- 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.
Response Out:
-
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 Object Framework DAO Database Table(s) DO Hibernate Domain Delegate DO DTO Dozer Data Transfer DTO XML JAXB -
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.
-
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/Function Pattern Code You Write Generated Code Framework Data Access DAO/Repository DAO Interface,
DAO Implementation class,
DAOTest,
Test Seed DataUnitils,
DBUnitDomain DO Domain class DomainTest Persistence ORM Domain Class ORM Mappings,
ORM Mapping TestHibernate,
ORMUnitData Transfer DTO XSD DTO JAXB DTO Assembly Assembler Mapping DO-DTO Mapping Dozer Delegate Business Delegate Code to translate DO's to DTO's Facade Facade Remote Service,
EJB,
Web ServiceController 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.
-
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.
-
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.
-
Packaging and Deployment Details
Layer Deployment Artifact Name Module Contents Spring Configuration File(s) Client/Controller loanapp-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
-
-
08 Dec 11
-
12 Nov 11
-
10 Nov 11
-
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.
-
-
26 Oct 11
-
13 Oct 11
-
10 Sep 11
-
31 Aug 11
-
09 Aug 11
-
28 Jun 11
-
31 May 11
Shinya YanagiharaProject Managementの視点でDDDを語っているが、それほど深い洞察があるわけでもない。サンプルをダイアグラム見たけど、ドメインにロジックがほとんどなくドメイン貧血症に見えた。
ドメインモデルのダイアグラムにRepositoryを記述するのも僕だったら避ける。
DDDを語るには良いドメインモデルとは思わない。 -
23 Mar 11
-
structure
-
-
22 Feb 11
-
05 Feb 11
smostafakIn this article, Srini Penchikala discusses Domain Driven Design and Development from a practical stand-point. The article looks at architectural and design guidelines and best practices that can be used in a DDD project. It also talks about the impact of
-
06 Dec 10
-
08 Nov 10
-
26 Oct 10
-
19 Oct 10
-
17 Oct 10
-
05 Oct 10
-
28 Sep 10
-
02 Sep 10
-
17 Aug 10
-
28 Jul 10
-
13 Jul 10
-
29 Jun 10
-
01 Jun 10
-
26 May 10
-
16 May 10
-
29 Apr 10
-
21 Apr 10
-
07 Apr 10
-
25 Feb 10
-
08 Feb 10
-
03 Dec 09
-
27 Nov 09
-
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.
-
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 SOA effort should include the design and implementation of the domain model
-
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
-
With a rich domain implementation, SOA design will become relatively simple by providing a shell (proxy) to the domain objects
-
-
19 Nov 09
-
01 Nov 09
-
27 Oct 09
-
23 Sep 09
-
19 Sep 09
-
20 May 09
Ben SmithThe 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.
architecture design development programming agile patterns domaindrivendesign ddd domain
-
18 May 09
-
14 Apr 09
-
23 Mar 09
-
- 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.
Let's look at the application and domain layers in more detail. The Application 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
The domain layer:
-
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.
-
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
-
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).
-
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.
-
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
-
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.
-
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.
-
- 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.
Following are some of these anti-patterns:
-
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).
-
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.
-
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.
-
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.
-
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.
-
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.
-
Article is great in promoting Domain Driven Design, but the sample application code does not express the domain concepts in java objects so well.
-
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.
-
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 object and an entity object is crucial.
-
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.
-
-
14 Mar 09
-
12 Mar 09
-
11 Mar 09
-
06 Jan 09
-
09 Dec 08
-
18 Nov 08
-
Most of the writings and articles on this topic have been based on Eric Evans' book "Domain Driven Design"
-
cover the domain modeling and design from a practical stand-point
-
The sample application uses frameworks like Spring, Dozer, Spring Security, JAXB, Arid POJOs and Spring Dynamic Modules
-
mere data carriers
-
domain specific business logic and rules being scattered
-
a specific business operational domain
-
loosely coupled
-
a POJO programming model without any technology or framework dependencies
-
agile methodologies focus on the delivery of business value
-
Using SCRUM (for project management) and XP (for software development purposes) methodologies is a good combination for managing a DDD implementation project.
-
Ramnivas Laddad recommends the following steps
-
more focus on domain objects than services in the domain model.
-
perform the basic (non-business related) validation on the user input data
-
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.
-

-
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.
-
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.
-
uses custom Aspects to introduce data caching into the Service objects.
-
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).
-
AnnotationBeanConfigurerAspect, AbstractInterfaceDrivenDependencyInjectionAspect, and AbstractDependencyInjectionAspect
-
These objects also use @Configurable annotation to wire the Repository objects.
-
authorization is managed at the class method invocation level.
-
Database DB object level authorization (Stored procedures, Stored functions, Triggers) -
They define data validation
-
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.
-
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.
-
scripting languages such as Ruby, Groovy, or Domain Specific Languages (DSL) are a better choice to define and manage these rules.
-
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.
-
Temporal Patterns: These patterns add time dimension to rich domain models. Bitemporal framework, which is based on Martin Fowler's Temporal Patterns,
-
DAO is the contract between relational database and the application.
-
a Repository is a separate abstraction that interacts with the DAOs and provides "business interfaces" to the domain model.
-
the web application
-
DAO methods are fine-grained and closer to the database while the Repository methods are more coarse-grained and closer to the domain.
-
The domain objects should depend only on Repository interfaces.
-
DAO classes should never be called directly from the client (Services and other consumer classes).
-
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.
-
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.
-
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.
-
Domain object model structurally is not compatible with the messages that are received and sent from a business service.
-
Hibernate Interceptor.
-
Spring-WS for marshalling and unmarshalling the data
-
a circular dependency between "domain" and "repository" sub-packages.
-
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).
-
you would have a generic persistence object, or a base persistence object for instance, which takes a class type and an object.
-
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.
-
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.
-
No daos and no repositories to be implemented, just plain domain classes!
-
Domain comes first and Infrastructure comes second.
-
-
16 Oct 08
-
01 Sep 08
-
06 Aug 08
-
23 Jul 08
-
14 Jul 08
-
06 Jul 08
-
30 Jun 08
-
29 Jun 08
-
27 Jun 08
-
25 Jun 08
-
24 Jun 08
Emmanuel HugonnetThe 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 t
-
23 Jun 08
-
21 Jun 08
-
19 Jun 08
-
Domain Driven Design and Development In Practice
-
Would you like to comment?
Join Diigo for a free account, or sign in if you are already a member.