The concept, difference and use of VO, DTO, DO, PO

https://blog.csdn.net/zjrbiancheng/article/details/6253232

 

 

Concept: VO (View Object): View object, used for presentation layer, its function is to encapsulate all the data of a specified page (or component). DTO (Data Transfer Object): data transfer object, this concept comes from the J2EE design pattern, the original purpose is to provide coarse-grained data entities for EJB distributed applications, in order to reduce the number of distributed calls, thereby improving distributed calls performance and reduce network load, but here I generally refer to the objects used for data transfer between the presentation layer and the service layer. DO (Domain Object): Domain objects are tangible or intangible business entities abstracted from the real world. PO (Persistent Object): Persistent object, which forms a one-to-one mapping relationship with the data structure of the persistence layer (usually a relational database). If the persistence layer is a relational database, then each field in the data table ( or several) corresponds to one (or several) attributes of PO.

The difference between VO and DTO You may have a question (in the projects I participated in, many programmers also have the same doubt): Since DTO is the object that transfers data between the presentation layer and the service layer, why do you need a VO? right! For most application scenarios, the attribute values ​​of DTO and VO are basically the same, and they are usually POJOs, so there is no need to do more, but don't forget that this is the thinking at the implementation level. For the design level, the concept There should still be VO and DTO, because there are essential differences between the two. DTO represents the data that the service layer needs to receive and returns, and VO represents the data that the display layer needs to display. It may be easier to understand with an example: for example, the service layer has a getUser method that returns a system user, one of which is gender (gender). For the service layer, it is only defined semantically: 1-male , 2-female, 0-unspecified, while for the presentation layer it might need to use "handsome" for males, "beautiful" for females, and "secret" for unspecified. Having said that, you may also refute, wouldn't it be enough to just return "handsome guys and beauties" at the service level? For most applications, this is not a problem, but imagine if the requirements allow customers to customize styles, and different styles represent "gender" differently, or if the service is used by multiple clients at the same time (different portals) ), and different clients have different requirements for the presentation layer, then the problem comes. Furthermore, returning to the analysis at the design level, from the point of view of the principle of single responsibility, the service layer is only responsible for the business and has nothing to do with the specific form of expression. Therefore, the DTO returned by it should not be coupled with the form of expression. Theory belongs to theory. In the end, this is still thinking at the level of analysis and design. Is it necessary to do so at the level of implementation? A one-size-fits-all approach is often not worth the loss, and I'll analyze how to make the right choice in the application below.

Application of VO and DTO The above is just a simple example to illustrate the conceptual difference between VO and DTO. This section will tell you how to make the right choice in the application. In the following scenarios, we can consider combining VO and DTO into one (note: it is the implementation level): When the requirements are very clear and stable, and the client clearly has only one, there is no need to distinguish VO and DTO. , at this time VO can be retired, just use a DTO, why is VO retired instead of DTO? Going back to the design level, the responsibilities of the service layer should still not be coupled with the presentation layer. Therefore, for the previous example, you can easily understand that DTO still cannot use "beautiful boys and girls" for "gender". This conversion should depend on Scripting of the page (eg JavaScript) or other mechanism (JSTL, EL, CSS) Even if the client can be customized, or there are multiple different clients, if the client can use some technology (script or other mechanism) to achieve the transformation, It can also make VO retreat

The following scenarios need to give priority to the coexistence of VO and DTO: The reverse scenario of the above scenario is due to some technical reasons, such as when a framework (such as Flex) provides automatic conversion of POJOs to some Fields in the UI, you can consider defining VO at the implementation level , this trade-off depends entirely on the comparison between the improvement in development and maintenance efficiency brought about by the automatic conversion capability of the framework and the reduction in development and maintenance efficiency brought about by designing one more VO to do more. If a "big view" appears on the page, and all the data that make up this big view needs to call multiple services and return multiple DTOs to assemble (of course, this can also be replaced by the service layer providing a DTO that returns a large view at one time, But whether it is appropriate to provide such a method at the service layer needs to be weighed at the design level).

The difference between DTO and DO is first of all a conceptual difference. DTO is a data transfer object between the presentation layer and the service layer (which can be considered as an agreement between the two), while DO is an abstraction of various business roles in the real world. This leads to the difference in data between the two, such as UserInfo and User (for the naming rules of DTO and DO, see a previous blog post by the author), for a getUser method, it should never return the user in essence password, so UserInfo has at least one password less data than User. And in Domain Driven Design, as the first article in the series said, DO is not a simple POJO, it has domain business logic.

Application of DTO and DO From the example in the previous section, careful readers may find the problem: since the UserInfo returned by the getUser method should not contain password, there should be no password attribute definition, but if there is a createUser method at the same time , the incoming UserInfo needs to contain the user's password, what should I do? At the design level, the DTO passed by the presentation layer to the service layer is conceptually different from the DTO returned by the service layer to the presentation layer, but at the implementation level, we usually rarely do this (define two UserInfos, or even more) , because it is not very wise to do so, we can design a fully compatible DTO. When the service layer receives data, the attributes that should not be set by the display layer (such as the total price of the order should be determined by its unit price, quantity, discount etc.), regardless of whether the display layer is set, the service layer will ignore it, and when the service layer returns data, the corresponding attributes will not be set for the data that should not be returned (such as user passwords). One more note for DO: why not just return DO in the service layer? In this way, the encoding and conversion work of DTO can be omitted. The reasons are as follows: The essential difference between the two may lead to a one-to-one correspondence with each other. One DTO may correspond to multiple DOs, and vice versa, and even there is a many-to-many relationship between the two. relation. DO has some data that should not be known to the presentation layer. DO has business methods. If the DO is directly passed to the presentation layer, the code of the presentation layer can bypass the service layer and directly call operations that it should not access. For AOP-based interception service layer In terms of the mechanism for access control, this problem is particularly prominent, and the business method of calling DO in the presentation layer will also make the transaction difficult to control due to transaction problems. For some ORM frameworks (such as Hibernate), the "lazy loading" technology is usually used. If the DO is directly exposed to the presentation layer, for most cases, the presentation layer is not within the scope of the transaction (Open session in view is in most cases). case is not a worthy design), if it tries to get an unloaded associated object while the Session is closed, a runtime exception (for Hibernate, LazyInitiliaztionException) will occur.

For DTO, it is also necessary to explain that DTO should be a "flat two-dimensional object", for example: if User will be associated with several other entities (such as Address, Account, Region, etc.), then getUser Does the UserInfo returned by () need to return all the DTOs of its associated objects? If this is the case, it will inevitably lead to a large increase in the amount of data transmission. For distributed applications, this design is even more unacceptable due to the transmission, serialization and deserialization of data on the network. If getUser needs to return an AccountId, AccountName, RegionId, RegionName in addition to the basic information of User, then please define these attributes in UserInfo, and "squeeze" a "stereo" object tree into a "flat" The two-dimensional object", the project the author is currently involved in is a distributed system, which converts all the associated objects of an object into a DTO object tree of the same structure and returns them, regardless of the three-seven-two-one, resulting in very slow performance. .

The difference between DO and PO DO and PO are in one-to-one correspondence in most cases. PO is a POJO that only contains get/set methods, but some scenarios can still reflect the essential difference in concept between the two: DO Explicit persistence is not required in some scenarios. For example, a commodity discount strategy designed using the strategy pattern will derive the interface of the discount strategy and different discount strategy implementation classes. These discount strategy implementation classes can be regarded as DOs, but they only It resides in static memory and does not need to be persisted to the persistence layer. Therefore, there is no corresponding PO for this type of DO. In the same way, in some scenarios, PO does not have a corresponding DO. For example, there is a many-to-many relationship between Teacher and Student. In a relational database, this relationship needs to be represented as an intermediate table, which corresponds to a TeacherAndStudentPO The PO, but this PO has no practical significance in the business field, and it cannot correspond to any DO at all. It should be specially stated here that not all many-to-many relationships have business meanings, which are related to specific business scenarios. For example, the relationship between two POs will affect specific businesses, and there are multiple types of this relationship. A many-to-many relationship should also be expressed as a DO. Another example: there is a many-to-many relationship between "role" and "resource", and this relationship will obviously be expressed as a DO - "authority". In some cases, for a certain persistence strategy or performance considerations, a PO may correspond to multiple DOs, and vice versa. For example, the customer Customer has its contact information Contacts, here are two DOs of one-to-one relationship, but it may be out of performance considerations (extreme cases, right as an example), in order to reduce the connection query operation of the database, the Customer and Contacts two DO data is combined into one data table. Conversely, if a book Book has an attribute of cover, but this attribute is the binary data of a picture, and some query operations do not want to load the cover together, thus reducing the disk IO overhead, and assuming the ORM framework If attribute-level lazy loading is not supported, then you need to consider separate covers into a data table, so that a DO corresponds to a PO. Some attribute values ​​of PO have no meaning to DO. These attribute values ​​may be data that exists to solve some persistence strategies. For example, in order to implement "optimistic locking", PO has a version attribute, which is for DO. It doesn't make any business sense and it shouldn't exist in DO. Similarly, there may also be properties in DO that do not need to be persisted.

The application of DO and PO is very popular due to the very powerful functions of the ORM framework, and JavaEE has also introduced the JPA specification. Nowadays, business application development basically does not need to distinguish between DO and PO. PO can be completely hidden through JPA, Hibernate Annotations/hbm among DOs. Even so, we must pay attention to some issues: For properties that do not need to be persistent in DO, they need to be explicitly declared through ORM, such as: in JPA, you can use @Transient declaration. For the attribute in PO that exists for a certain persistence strategy, such as version, because DO and PO are merged, it must be declared in DO, but because this attribute has no business meaning to DO, it needs to be hidden from the outside world. , the most common practice is to privatize the get/set method of the property, and even not provide the get/set method, but for Hibernate, this needs special attention, because Hibernate reads data from the database and converts it to DO. The reflection mechanism first calls the empty parameter constructor of DO to construct a DO instance, and then uses the JavaBean specification to reflect the set method to set the value for each property. If the set method is not explicitly declared, or the set method is set to private, it will cause Hibernate cannot initialize DO, resulting in a runtime exception. The feasible approach is to set the property's set method to protected. Hibernate provides good support for scenarios where one DO corresponds to multiple POs, or one PO corresponds to multiple DOs, as well as property-level lazy loading. Please refer to the related information of Hibnate.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325949482&siteId=291194637
Recommended