A text interpretation anemia / hyperemia model 1 (rpm)

  Would like to discuss this topic is related to domain-driven design, the use of anemia, blood loss or congestion model and domain-driven design. Before that I'd like to discuss current issues in many applications, I think the cause of this topic is because I see such an article, "In the above InfoQ biggest flaw Spring Web applications ," have to say, this title quite attractive ( '· ω · `). The main content and viewpoints something like this, and now most of the applications Spring Java Web application frameworks are quite concerned about the single responsibility principle and separation of concerns principle , but on top of this was the birth of some of the less good anti-patterns and design principles, such as :

  • Field of the object model is only used to store application data (anemia domain model using anti-pattern model).
  • Business logic at the service layer, object management data region.
  • In the service layer, each corresponding to a service application entity class.

  This type of design principle is widely used, I am now the project is to use the Java Web This design architecture design principles, the basic three or more layers are common architecture, about what they like?

  1. Web layer (commonly known as the presentation layer, right, Presentation Layer): receiving a user input, the data transmitted to the service layer;
  2. Service Layer (Service Layer, can be called Business Logic Layer): transaction boundaries, the business logic processing, rights management and authorization, and communicate with the storage layer;
  3. Memory layer (Data access layer): communicating with a database, data persistence.

  But found nothing? The problem lies in the service layer, he suffered a lot of responsibility, transaction management, business logic, and so on like permission checks, which violates the single responsibility principle and the principle of separation of concerns and generated a lot of dependence and circular dependencies. When the business complexity increases, the code contained in the service layer will be very large and complex, a direct result of the rise in the cost of test.

  I happen to have here an example, in the current project, responsible for handling the insurance business units of core classes, including more than 4,000 lines of code, it is a key to the database table associated with the reference (injection) a dozen DAO . In dozens of kinds of methods that can handle the policy, reinsurance, claims and so on a variety of business, but it also depends on the depth of Hibernate, ORM approach to not only use the data, and even the direct use HQL to get the data . Because there are many other service classes circular reference with him, the project later this monster no one dares to change, because no one knows what he can do in the end, the reconstruction is impossible.

  Said some bad things about the service layer, it should be how to improve it?

  • First, we need to move the business logic from the service layer to the domain model, this advantage is that the service can only be responsible for the application logic layer (such as data validation, authorization checks, start and end the transaction, etc.), may be responsible for their domain model related business logic. Or in the distance before the policy system, completely against the policy, reinsurance architecture design, claims and other fields models modeling related business models can be placed in different areas, respectively, some of the likely repeat business codes are collected at one place, thereby reducing the copy - the possibility of paste.
  • Secondly, the service class will become smaller, so that it is only responsible for a single role. The article is an example, and other operations such as CRUD user account, you can put it into two different classes of service, one for CRUD operations account, and the other in charge of other operations related to the user account.

  This enables the service class becomes small, loose, can be tested, while reducing the cost of other people to understand and reuse.

  The next question is, in the actual project, how to practice these design principles?

  There is a " domain-driven design and development practices " well worth a look, he respected the hierarchy and above similar, and even made some more details of the rules:

  • Service layer needs to contain application logic, management of user sessions, but can not contain domain logic, business logic and data access logic;
  • FIELD layer (art objects) should contain the business logic can handle session state associated with the service. But as the core business applications should have good portability, can not produce dependence on the particular framework (e.g., Struts, Hibernate, EJB, etc.).

 

  Here, finally to the topic of discussion - anemia, blood loss and congestion model. What is the blood loss anemia congestion model it? simply put

  • Bleeding models: model only contains data definitions and getter / setter methods, application logic and the business logic into the service layer. This class is called POJO in Java, called in .NET POCO.
  • Anemia Model: Anemia model contains some business logic, but does not include business logic dependent persistence. This part of the business logic layer will depend on lasting into the service layer. As can be seen, the object field anemia model is not dependent on the persistence layer.
  • Congestive Model: hyperemia model includes all the business logic, including persistence depends on the business logic layer. Therefore, the use of the domain layer congestion model is dependent on the persistence layer, simply indicate that the UI layer -> Services Layer -> Layer field <-> persistence layer.
  • Expansion Model Blood: Blood expansion model is to other application logic (e.g., authorization, transaction, etc.) and does not want business logic related art are placed in the model. I feel the blood swelling but the model is another model of blood loss, because the service layer disappears, the domain layer service layer of dry matter, in the end still nothing has changed.

  Can see, blood loss model and expansion model blood are not desirable, the question now is, anemia and congestive model model which is more better. A long time ago, people were protracted controversy address this issue, in the end still no results. Here are some posts available aftertaste:

  Anemia, congestive interpretation model and some experience

  To summarize recent domain object and the related discussions on

  The main focus of debate both sides in the two sentences I bolded above, the domain model is dependent on whether or not to persistence layer, because dependent on the persistence layer means to expand the unit testing more difficult (not to test out the framework to discuss the text of herein refers specifically to the Hibernate), more difficult to separate layers art, and will more difficult to peel from the application, of course, not necessary to mix the benefits of business logic in different layers, so that better reflects the properties of a single role. Proponents (hyperemia model) that as long as the persistence layer abstracts, you can reduce the difficulty of the test, after all, apply congestion model brings the convenience of many developers, apart from relying on persistence layer that has more hyperemia model is still worth taking advantage of. Finally, no one can convince choose how anemic model and the model of congestion, more rely on specific business scenarios to decide, and we can not say which one is better than which. Design patterns such things are not always what no conclusive.

  I personally tend to use congestion model, because congestion model is more like a well-designed system architecture, and good computer world, there are a lot of IOC and DI framework, the only flaw dependent on the persistence layer can be bypassed by a variety of alternative methods, with with advances in technology, some drawbacks will be gradually solved. My idea is this: first persistence layer of abstraction for the interface, and then through the persistence layer service layer is injected into the domain model, this model will only depend on the area of ​​the interface persistence layer. And this interface, may be abstracted using existing technology framework. For example, Java version of Hibernate I do not know much, with regard to the .NET Entity Framework for instance:

  Now there is such a DbContext, we all know, DbContext and DbSet is very bad Mock two classes (I was just too troublesome, experts please ignore), there are two tables, one called the other Animes call Users

  How to design an interface to make both easy to use and you can easily test it? Direct extraction of an interface? DbSet not easy Mock problem is not solved it.

 

  Fortunately, we have LINQ and IQueryable <T>, just transform the look, the interface becomes this:

   Note Query <T> () method, which returns an IQueryable <T> object, which implements IQueryable LINQ object is to support the operation, that is, we can still be true to the search of Expression DbContext to do, and this DbContext need only a simple sentence:

  From from a in db.Anime.AsQueryable () into a query from a in db.Query <Anime> (), everything is settled. When you want to return a false data source in the unit test time, directly FakeDb.Query <T> () method returns false data have a List <T> .AsQueryable () on it. This realization of the domain layer and the persistence layer of decoupling, after all, is generic IQueryable thing.

Guess you like

Origin www.cnblogs.com/IT-Evan/p/Model1.html