1. Question about populate data in action:
One of the responsibilities of action is to create an instance of the domain object and populate the data from the page to the instance. In this process, there is a problem: if a new object requires another domain object, at this time, the page passes only the ID of this object, how will this propoerty be set?
For example, in the action for creating a thread, to set forum for the new thread, and only the Forum ID is sent from the page, the Forum is loaded in the action, and set it to thread or in service?
Solution: Using DTO will solve this series of problems! At the same time, the domain layer has better self-encapsulation. Opensessioninview is no longer required! DTO is only the carrier of data, which is compatible with the basic needs of the presentation layer (only reading and writing data without business processing. After DTO arrives at the service, it is good to disassemble the data and perform a series of business operations.
The advantage of introducing DTO is that domain objects can be encapsulated inside the domain model. Essentially, the view layer only needs data obtained from the domain layer. Of course, it also has its own logic, but these are all presentation logic, which is irrelevant to the business. Therefore, I should just transfer the data. In addition, if domain objects are used as data carriers for transmission between the domain layer and the presentation layer, there may be some problems: If domain objects are complex to be created, it is inconvenient to create a domain object in action, because after all, it is not in the domain model. In a simple example, if object A is created through the factory method of object B, it will be weird to write this in action. In addition, DTO is not one-to-one correspondence with domain objects. It is coarse-grained and oriented to the view layer. This is also the purpose of introducing DTO.
2. Set the intent for service and data at the application layer.
Obviously, at the application layer, there is no encapsulation of Object-oriented Data and behavior. Therefore, the Service undertakes "behavior" and "data" carried by data ". In the application layer, we will create a domain object, populate the data value to the domain object, and then perform business operations through the Business Method of the domain object. This model is very reasonable and effective.
3. Questions about dtoassembler Assembly DTO:
In general, it is no problem to extract data from a domain object and assemble DTO, because the domain object contains all
Possible data is only a selection process when assembling DTO. But in turn, there may be problems.
. For example, to save a thread, you need to set its forum. Threa passed from the page
In addition to the basic thread information, ddto also provides a forumid. for the worker er, if you want to assemble a thread object, you need to load a forum instance through forumid (Note: In hibernate, you need to use session. load Method loads a proxy, so that it will not be efficient), but this requires the assistance of repository.
4. Thinking about whether to introduce servicefacade
Dto has been introduced in the project. According to the standard J2EE mode, DTO is always used with servicefacade (the amendment made in April 27: DTO is not only used with servicefacade, but basically we need to introduce DTO, then applicationservice will also use DTO. It does not mean that DTO can only appear in the facade interface. This is reflected in both poeaa and corej2eepatterns ). My thoughts on whether to introduce this component are as follows:
Traditionally, DTO is a data structure oriented to the client (or the presentation layer). servicefacade is a useraction oriented to the client, or usecase. DTO and servicefacade are combined to form an adapter between a client (or presentation layer) and a business layer (domain model. Typically, if a useraction requires multiple services to work together before it can be written, the role of servicefacade is highlighted. It does not have business logic, but it delegates the action request to the appropriate service for processing.
This concept seems reasonable, but it is not easy to use. First, there is a problem about the granularity of Facade and service. If a facade method corresponds to an action, what kind of useraction needs to be delegated to multiple services? What should I do? What is the service granularity standard? Some people say that a service is business-oriented (especially in transactionscript projects). I think it is actually internal business processing, which of its methods are oriented (or based on what) to form a method? I think this standard is not easy to find. We only have one of the most consistent standards: user requests, that is, the granularity standard of facade. The problem is that there is no clear standard for the granularity between facade and service. Strictly speaking, facade and service are both application-layer products. The role of the application layer is to delegate external application requests (such as a useraction) to the domain layer for processing. From this point of view, the granularity of the application layer interface is only one layer of standard. I think there is really no good granularity splitting standard between facade and service. In most cases, the next facade method is delegated to a service method, which proves this. So I think it is better to combine the two into a concise and neat one. As for the fact that more than two existing actions need to execute the same set of business operations, we will reconstruct this group of operations into an independent service method.
April 27: I have some new ideas on servicefacade and appliationservice:
As mentioned above, when a user request requires multiple services to be processed together, the role of facade will be highlighted, which is indeed the decisive reason for the introduction of facade. I think this situation does exist. In this case, the Controller Method of the client can call more than two services to delegate user requests. This is a signal, indicating that these services should be encapsulated into a unified facade. Or reverse inference: if a certain specification requires that we only use one service interface to process this request, you may think, do you need to make this service dependent on the services used? Obviously, dependencies cannot be used between services. This also indicates from the reverse, we really need a higher level of encapsulation to put these services together.
Basically, applicationservice is organized by entities, especially the aggregation root. I believe there will be some very high-level requests that need to be implemented across multiple entities or aggregates. In this case, we need facade.
This is the level of granularity between service and facade that I have been thinking about over and over again. The following is a brief summary:Applicationservice is organized by entities, especially the aggregation root. Its interfaces are directly oriented to use cases (User requestor is useraction. however, there is no definite limit on the granularity of a facade (maybe you can design a facade for a module), but its lower limit is very clear, that is, services that span more than two entities or aggregate use cases. Its interfaces are also case-oriented.
However, you need to note that useraction may be a strength standard, but a useraction may be large or small, and sometimes the gap is large. This should be noted.
PS: the data transmitted from these service interfaces is still DTO.
: Today, after reading "poeaa", I have a deeper understanding of this issue.
You don't see remote Facade used with a transaction script (110) as a rule, since a transaction script (110) is inherently coarser grained.
First, it must be clear that remotefacade only exists in the domainmodel-based system architecture. Because domain objects are fine-grained, they need facade. While transactionscript systems do not, because transactionscript is inherently coarse-grained!
Review of the service layer:
I think service is the application API and the best level of transaction and security management.
In the system based on transactionscript, the service is very heavy and contains the vast majority of page service logic.
In a domainmodel-based system, the service is just a thin interface, or a domainmodel facade. It delegates domain objects to complete business processing.
Applications implement use cases that coordinate multiple business objects (374) and services. however, you shouldn't implement use case-coordinating behavior specifically within business objects (374), because it increases coupling and reduces cohesion between these business objects (374 ). likewise, you don't have want to add this business logic to a service facade, because the business logic potentially gets duplicated among different facades, which references the reusability and maintainability of common code.
To implement a use case (or simply say a useraction), there are two logics in domainmodel, one is the behavior logic of the domain object itself (that is, the method ), the other part is the logic for coordinating objects in various fields, which is also a very important part. You cannot write this part of logic into the domain object, so that the domain object will be coupled. Where is the logic?Application ServiceIn!
Applicationservice includes business logic. Its business logic is the logic of how to collaborate between objects in the domain! In itself, it is the facade of the domain object!
In non-EJB applications, where you need to reduce coupling between the presentation-tier components and business-tier components such as business objects (374) and other services, application Services provide that intermediary function between the two tiers. an Application Service exposes a finer-grained interface than a service facade and a coarser-grained interface than the underlying business objects (374) and other services.
Application service interfaces are finer than servicefacade interfaces and coarse than domain objects. They are case-oriented!
Servicefacade is another kind of thing. It is the facade of applicationservice. What is servicefacade designed? We are back to the beginning!
Please refer to the samplecode in the applicationservice section of core J2EE patterns. I think it is more appropriate for a facade to correspond to a module, but why should we design this facade?
But at least one thing we are very clear about now:
That is, the data transmitted from applicationservice is DTO! This is verified in the code of poeaa and core J2EE patterns, and the role of applicationservice determines that it should use DTO! (Of course, in the system where DTO is needed)
About DTO and dependent domain objects:
When persist/update is required for a domain object, page data is transmitted to the service in the form of DTO. When the domain object is dependent on other domain objects, the ID of this object is usually uploaded to the page. So how do we load these objects by ID and set the relationship between them?
For example, when we create a new thread, it will depend on the object with a forum and a user. Then, the page is sent to the service only with a forumid and a userid. We have two problems:
1. Whether these IDs are put in DTO or passed as parameters separately.
2. Where to load these entities and associate them with the thread.
Think about 2nd first: I have a clear tendency at present, that is, the job of loading these entities and associating them with the thread should not be put into the handler! Because the association of entities itself is part of the business logic, putting them in the handler will cause the business logic to "flow out ". For another reason, in many cases, relational entities may not be handled simply by a simple set, but may have complicated business logic. Therefore, I tend to load objects in the service and associate them. This also ensures that the consumer er will not depend on any repository!
1st issues are not very important. Put it in DTO should make the service interface concise.
Why does the createpost () method of Forum's createthread () and thread be removed?
After thinking about it, I also removed these simple factory methods. Now, I think the principle can be recorded as an experience:
I think the factory method is best to produce complete products. If a semi-finished product is produced and we need to assign a value and process it elsewhere, the factory method may not be necessary?
Application Service K: a solution for dispatch domain events like swiz, and then delegate to repository for data access!
A
A
A
A