From the anemic domain model to the rich domain model

Source: Internet
Author: User
Tags in domain

Transferred from: http://www.uml.org.cn/mxdx/200907132.asp


In the current developer community, there is a widespread prevalence of an architectural pattern known as the anemic domain model by Martin Fowler. The model has been blamed for the criticism of the master. This model has a fatal flaw: it often behaves poorly in dealing with complex areas. There are many indications that when we face complex applications, it is best to turn to a framework based on a rich domain model.

While the rich domain model has obvious benefits, it also poses challenges for practice, both for technical reasons and for design methods. For the construction of technology, such as annotation, aspect and Di and other complex technologies, the use of the final can be clearly mastered, but in the design method, often due to different practices and difficult to achieve consensus.

The purpose of this paper is simply to provide a method for transforming the anemic domain model into a rich domain model, which can be used for peer reference with the same needs.

1. Prerequisites and Limitations

Regardless of which domain model is used, support for some tools is often required, including the IOC container and the O/R mapping tool. Due to the author's experience, when referring to these tools, it only means spring and hibernate in the Java world.

For a description of the anemia domain model, please refer to:

Http://www.martinfowler.com/bliki/AnemicDomainModel.html

For best practices in the anemic domain model, please refer to:

Https://appfuse.dev.java.net

The most authoritative guide to enriching the domain model is available at:

http://www.domaindrivendesign.org

Because of the different contexts, different hierarchical patterns of terminology have different meanings, but the tasks they want to achieve can be separated, and these tasks have not caused extensive semantic confusion at present. To better compare the two architectural patterns mentioned in this article, define the tasks they want to accomplish as follows:

Task

Describe

Performance logic

Receives a request from outside the system, proxies the request to another module, and renders the returned processing result in some way to the requestor.

Application logic

is the implementation of the appearance of the use case, which coordinates the actual implementation of the use case to complete an application-related function.

Domain logic

Model the most essential content of the problem domain to realize the function of user's core value.

Persistence logic

interacts with the external storage of the data.

Basic services

More technology-centric, providing basic support for each module of the software system.

2. Anemia Domain Model Framework

2.1. Layered mode

They also have different styles, even if they are labeled with anemic models. The following is a more typical one:

Layer

Task

Object

Description

Presentation

Display logic

Model objects

Models. The Entity/value object in the domain layer can also be used as a standalone object.

View

View

Controller

Controller. A response to a user request is obtained through a mechanism.

Domain layer

Mixed application logic in domain logic

Service

Service. Process domain logic and application logic at the same time

Entity

Entities. Static view of the domain model

Data source layer

Persist logic

DAO object

is implemented in many ways, such as JDBC, Hibernate, IBATIS, JPA, EJB CMP

Infrastructure layer

Basic services

2.2. Sample Code

Now suppose there is an online shopping site where we want to browse the product list and then select an item of interest, and we need to see the product details.

1) The page makes a request

The following is a possible JSF code fragment:

<f:param value= "#{product.id}" Name= "ProductID" ></f:param>

2) Assign to Controller

Suppose the request is dispatched to the controller yourpackage.action.ProductAction:

Package yourpackage.action;

......

public class Productaction extends Baseaction {

Through the service of dependency injection

Private Productservice Productservice;

The Realm object as a model object

Private product product;

Private Integer ID;

Responding to events that view product information

Public String edit () {

Product = productservice.getproduct (ID);

return "Product"; JSF resolves it to a product.xhtml view

}

}

3) service at the domain level

Typically there is a service interface Productservice, then the implementation of the interface Productserviceimpl:

Package yourpackage.service;

......

public class Productserviceimpl extends Baseservice implements Productservice {

By relying on the injected DAO object

Private Productdao Productdao;

Domain logical approach to obtaining product information

Public Product getproduct (Integer ID) {

return productdao.getproduct (ID);

}

}

4) Entity of the domain layer

The following is a JPA-style entity that is used to host data only, without domain behavior (which is why anemia is called).

Package Yourpackage.model;

......

@Entity

public class Product {

@Id @GeneratedValue (Strategy=generationtype.auto)

@Column (name= "Id")

Public Long getId () {

return ID;

}

@Column (name= "name", Length=30, Nullable=false)

Public String GetName () {

return name;

}

}

5) DAO Object

There is also a need for an interface, which implements the class if it is JPA:

Package Yourpackage.dao;

......

public class PRODUCTDAOJPA extends BASEDAOJPA implements Productdao {

Public Product getproduct (Integer ID) {

Return (Product) getjpatemplate (). Find (Product.class, id);;

}

......

}

2.3. Analysis

Advantages:

* Get the most basic benefits of layering.

* Easy to understand, fast to master: No more complex techniques are used, and there are a wealth of sample resources.

* With extensive tool support, it is very easy to benefit from the Spring/hibernate type of framework.

* Suitable for the simple model, the CRUD operation is the main field.

Disadvantages:

* The area of the model is lacking in expressive capacity.

* Code responsibility Assignment is unreasonable.

3. Enrich the domain model

3.1 Tiered Mode

The typical DDD style layering pattern is as follows:

Layer

Task

Object

Describe

Presentation Layer

Performance logic

Model objects

The Entity/value object in the domain layer can also be used as a standalone object.

View

Controller

Application Layer

Application logic

Service

Modeling the use case

Domain Layer

Domain logic

Service

Modeling domain Operations

Entity

Model domain concepts and can be persisted

Value Object

Value Object. Modeling Domain Concepts

Storage Library

Repository. Isolation persistence

Basic facilities

Persistent logic and basic services

Data mapping

Persistent operations are typically encapsulated in DAO mode

Basic services

In practice, I personally prefer to separate the data mapping from the infrastructure layer, which will have a clearer hierarchy.

Regardless of the domain model, there has been controversy over whether to pass domain objects to the presentation layer as model data. Making the right design decisions requires a balance of flexibility and rigor. There are a number of technical methods that enable domain objects to be protected as DTO objects, as can be found in the following article, "Protecting the domain Model":

Http://api.blogs.com/the_catch_blog/2005/05/protecting_the_.html

These practices have partly compensated for the negative impact of direct-transfer domain objects.

3.2 What's different.

From the table above we can find that the things to do are still those things, but part of the responsibility is reassigned. In relation to the anemic domain model, in the new layering mode:

* Unchanged is the presentation layer;

* The data source layer is merged and is now part of the infrastructure;

* Added is the application layer;

* The domain layer is being re-organized and its responsibilities are assigned to the appropriate objects: Entities, value objects, services, and repositories.

The biggest changes here are three:

1) The application logic is separated from the domain logic to form a new application layer. The interface of the layer is designed according to the use case, so the granularity is large, and the layer reflects the tasks implemented by the system and can reflect the workflow if necessary.

2) The domain layer reflects only the most central part of the domain logic and is therefore the most complex (if the domain is more complex than the technical complexity). The entity not only holds the data, but also has the rich behavior; The service is a field-related operation (this differs from the application-tier service and the service at the infrastructure level), and the connection to the data technology is isolated through the repository.

3) The domain layer can independently access services and resources from other tiers. This is a controversial topic and is technically challenging, as explained in the example code below.

4. Refactoring to a rich domain model architecture

4.1. Technical Solutions

For simplicity, the aliases of A and B are used to represent the "anemic domain Model" and the "Enrich domain Model", respectively, using namespaces to represent layers in the model, such as B:: The application layer represents the application layer of the rich domain model.

With the previous comparison, it is easy to get the following conversion scenario:

1) Keep the performance layer unchanged

2) separate out the application layer. From a:: Domain layer Remove application logic Form B:: Application layer.

3) Refactor a purely domain layer. The domain logical part of a:: Domain layer is decomposed:

# Refactor The conceptual logic to the B:: Domain layer. Entity and B:: Domain layer. Value object;
# Refactor the operational logic to the B:: domain layer. Services;
# The data source access is abstracted as a repository interface, and the implementation of the repository is injected by the IOC container.

4) Reconstruct the data access object so that it implements the repository interface of the domain layer.

5) The infrastructure layer remains the same.

Do not explain more, the following code to explain.

4.2. Sample Code

Or the previous online shopping site, but this time uses a use case that slightly reflects the domain logic: list other products related to the current product.

1) The page makes a request

The following is a possible JSF code snippet:

Then, you need to specify the following in the JVM load parameter:

-javaagent: <path-to-ajlibs>/aspectjweaver.jar</path-to-ajlibs>

Now it's time to say it's done.

5) DAO Object

The interface that DAO needs to implement now becomes the productrepository of the domain layer:

Package Yourpackage.dao;

Import Yourpackage.domain;

......

public class PRODUCTDAOJPA extends BASEDAOJPA implements Productrepository {

Public Product getproduct (Integer ID) {

Return (Product) getjpatemplate (). Find (Product.class, id);;

}

Public Product getrelatedproduct (Integer ID) {

Here is the specific implementation code

}

}

5. Conclusion

To build a purely domain model, it is often necessary to use external services directly in the domain object, such as database access, external resources, or other necessary services. Without the support of strong annotation, AOP and Di technology, these external services or resources are difficult to inject into the domain object, thus creating the design style of the anemia model.

In particular, for spring users, the resolution of the issue has become easier after release of version 2.0. Using spring's integrated ASPECTJ implementations to inject dependency into domain objects enables domain objects to express richer logic and thus transition to rich domain models. After this key problem is solved, the remaining problems will be solved.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.