java 值对象模式和数据传输模式的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6986032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between Value Object pattern and Data Transfer pattern
提问by suri
In which scenario can I use those design patterns in n-tier architecture?
在哪种情况下我可以在 n 层架构中使用这些设计模式?
回答by Dmitry
DTO is the object that you can use at the boundariesof the system. When you have a SOAP web service for example and you want to return response you would use DTO. It easier to deal with than actual XML that has to be returned over the wire. DTOs are often generated by tools, based on WSDL for example. DTO are often tailored to the needs of service consumer and can be affected by performance requirements.
DTO 是您可以在系统边界使用的对象。例如,当您有一个 SOAP Web 服务并且想要返回响应时,您将使用 DTO。它比必须通过网络返回的实际 XML 更容易处理。DTO 通常由工具生成,例如基于 WSDL。DTO 通常是根据服务消费者的需求量身定制的,并且可能会受到性能要求的影响。
Value objects on the other hand live in the coreof the system. It captures pieces of business logic and maybe formatting rules. It makes your code more type safe and expressive. It also tackles "Primitive obsession" anti pattern. Good example is using class "SocialSecurityNumber" instead of string. Or Money instead of decimal. These objects should be immutable so that they look more like primitives and can be easily shared among different threads.
另一方面,值对象存在于系统的核心中。它捕获业务逻辑片段和格式规则。它使您的代码更加类型安全和富有表现力。它还解决了“原始痴迷”反模式。很好的例子是使用类“SocialSecurityNumber”而不是字符串。或 Money 而不是十进制。这些对象应该是不可变的,这样它们看起来更像原语,并且可以在不同的线程之间轻松共享。
For example in hypothetical 'customer-order' system:
例如在假设的“客户订单”系统中:
CustomerAndLastFiveOrdersis DTO (optimized to avoid multiple network calls)
CustomerAndLastFiveOrders是 DTO(优化以避免多次网络调用)
Customeris Entity
客户是实体
Moneyand SKUare Value objects
Money和SKU是 Value 对象
回答by Shivprasad Ktheitroadala
Comparing DTO objects with value objects is like comparing oranges and apples.
比较 DTO 对象和值对象就像比较橙子和苹果。
They serve completely different situations. DTO defines the object / class structure of how data will be transferred between layers while value objects defines the logic for equality when values are compared.
它们服务于完全不同的情况。DTO 定义了数据如何在层之间传输的对象/类结构,而值对象定义了比较值时是否相等的逻辑。
Let me explain you with examples, let us first try to understand value objects first :-
让我用例子来解释你,让我们先试着理解值对象:-
Value object is an object whose equality is based on the value rather than identity.
值对象是一个对象,其相等性基于值而不是身份。
Consider the below code we have created two objects of money one is one rupee coin and the other is a one rupee paper currency.
考虑下面的代码,我们创建了两个货币对象,一个是卢比硬币,另一个是一卢比纸币。
Money OneRupeeCoin = new Money();
OneRupeeCoin.Value = 1;
OneRupeeCoin.CurrencyType = "INR";
OneRupeeNote.Material = "Coin";
Money OneRupeeNote = new Money();
OneRupeeNote.Value = 1;
OneRupeeCoin.CurrencyType = "INR";
OneRupeeNote.Material = "Paper";
Now when you compare the above objects the below comparison should evaluate to true because 1 rupee note is equal to 1 rupee coin in real world.
现在,当您比较上述对象时,以下比较应评估为真,因为在现实世界中 1 卢比纸币等于 1 卢比硬币。
So either you are using “==” operator or you are using the “Equals” method the comparison should evaluate to true. By default “==” or “equals” will not evaluate to true so you need to use operator overriding and method overriding to get the desired behavior. You can see this linkwhich explains how to achieve the same.
因此,要么您使用“==”运算符,要么使用“Equals”方法,比较应评估为真。默认情况下,“==”或“equals”不会评估为真,因此您需要使用运算符覆盖和方法覆盖来获得所需的行为。你可以看到这个链接,它解释了如何实现相同的目标。
if (OneRupeeCoin==OneRupeeNote)
{
Console.WriteLine("They should be equal");
}
if (OneRupeeCoin.Equals(OneRupeeNote))
{
Console.WriteLine("They should be equal ");
}
Normally value objects are good candidates for immutability; you can read more about it from here. You can see this videowhich describes how immutable objects can be created.
通常,值对象是不变性的良好候选者;你可以从这里阅读更多关于它的信息。您可以观看此视频,其中描述了如何创建不可变对象。
Now let's try to understand DTO:-
现在让我们试着理解 DTO:-
DTO (Data Transfer objects) is a data container for moving simplifying data transfer between layers.
DTO(数据传输对象)是一个数据容器,用于移动简化层间数据传输。
They are also termed as transfer objects. DTO is only used to pass data and does not contain any business logic. They only have simple setters and getters.
它们也称为传输对象。DTO 仅用于传递数据,不包含任何业务逻辑。他们只有简单的 setter 和 getter。
For example consider the below call we are making two calls one to get customer data and the other to get product data.
例如,考虑下面的调用,我们进行了两次调用,一个是获取客户数据,另一个是获取产品数据。
DataAccessLayer dal = new DataAccessLayer();
//Call 1:- get Customer data
CustomerBO cust = dal.getCustomer(1001);
//Call 2:- get Products for the customer
ProductsBO prod = dal.getProduct(100);
So we can combine the Customer and Product class in to one class as shown below.
所以我们可以将 Customer 和 Product 类合并为一个类,如下所示。
class CustomerProductDTO
{
// Customer properties
public string CustomerName { get; set; }
// Product properties
public string ProductName { get; set; }
public double ProductCost { get; set; }
}
Now with one call we will be able to get both customer and product data. Data transfer objects are used in two scenarios one to improve remote calls and second to flatten object hierarchy; you can read this articlewhich explains more about data transfer objects.
现在只需一个电话,我们就可以获得客户和产品数据。数据传输对象用于两种场景,一是改进远程调用,二是扁平化对象层次结构;您可以阅读这篇文章,其中详细介绍了数据传输对象。
//Only one call
CustomerProductDTO cust = dal.getCustomer(1001);
Below is the complete comparison sheet.
下面是完整的比较表。
回答by Ryan Gross
There are several good answers here, but I'll add one to capture a key difference:
这里有几个很好的答案,但我会添加一个来捕捉一个关键的区别:
Value objects do not have an identity. That is, any comparison between two instances of a value object that contain should indicate that they are equal. Data Transfer Objects, while only being used to hold values, do have an identity. Comparing two instances of a DTO that have the same values, but were created independently, will not indicate that they are equal.
值对象没有标识。也就是说,包含值对象的两个实例之间的任何比较都应该表明它们是相等的。数据传输对象虽然仅用于保存值,但确实具有标识。比较具有相同值但独立创建的两个 DTO 实例不会表明它们相等。
Example:
例子:
DTO dto1 = new DTO(10);
DTO dto2 = new DTO(10);
dto1.equals(dto2); //False (if equals is not overridden)
dto1 == dto2; //False
VO vo1 = VO.getInstance(10);
VO vo2 = VO.getInstance(10);
vo1.equals(vo2); //True
vo1 == vo2; //True
It's slightly difficult to implement the Value Object pattern in Java, since the == operator always compares object identity. One way to do so would be to implement an object cache that returns the same object for each value.
在 Java 中实现值对象模式有点困难,因为 == 运算符总是比较对象标识。一种方法是实现一个对象缓存,为每个值返回相同的对象。
public class VO {
Map<Integer, WeakReference<VO>> cache = new LinkedHashMap<Integer, WeakReference<VO>>();
public static VO getInstance(int value) {
VO cached = cache.get(value);
if(cached == null) {
cached = new VO(value);
cache.put(value, new WeakReference<VO>(cached));
}
return cached.get();
}
private int value;
private VO(int value) {
this.value = value;
}
}
回答by duffymo
I would advise against the data transfer object. It's an EJB 1.0 anti-pattern, in my opinion, given value by those who insist in layer purity.
我建议不要使用数据传输对象。在我看来,这是一种 EJB 1.0 反模式,它被那些坚持层纯度的人赋予了价值。
A value object is useful. It's usually an immutable object, like Money. They should be thread-safe.
值对象很有用。它通常是一个不可变的对象,比如 Money。它们应该是线程安全的。
回答by Nathan Hughes
A value object is something that is useful to encapsulate as an object, but it has no identity. Compare it to an entity, which is something that does have identity. So in an order-processing system a Customer or an Order or a LineItem are concepts that point back to specific people or things or events, so they are entities, where a value object is something like a monetary amount, that doesn't have an independent existence of its own. For instance, for a system where part of the application involved calculating how to divide a payment between different accounts, I created an immutable Money object that had a divide method that returned an array of Money objects evenly splitting the original object's amount across them, that way the code for dividing amounts was in a place that was handy where the person writing the jsp could use it, and they didn't have to mess up the jsp with non-presentation-related code.
值对象是可以封装为对象的有用的东西,但它没有身份。将其与实体进行比较,实体确实具有身份。因此,在订单处理系统中,客户或订单或 LineItem 是指向特定人员或事物或事件的概念,因此它们是实体,其中的值对象是类似于货币金额的东西,没有自己独立存在。例如,对于应用程序的一部分涉及计算如何在不同帐户之间分配付款的系统,我创建了一个不可变的 Money 对象,该对象具有一个 Division 方法,该方法返回一个 Money 对象数组,将原始对象的金额平均分配给它们,即用于划分数量的代码放在一个方便编写jsp的人可以使用它的地方,
A Data Transfer Object is a wrapper for bundling things together for sending across application tiers or layers. The idea is that you want to minimize the amount of network back-and-forth traffic by designing methods that send large bundles of information.
数据传输对象是将事物捆绑在一起以便跨应用程序层或层发送的包装器。这个想法是您希望通过设计发送大量信息的方法来最小化网络来回流量。
回答by Geekjava90
Data Transfer Object is used to set property values which is coming from database in Data Access Layer (DAO), whereas using VO pattern we can set values in controller layer of MVC that are already set in DAO Layer. Client can have access to VO objects rather than DTO's which he/she can iterate in jsp page. You can say there is a separation of concern for both layers.
数据传输对象用于在数据访问层 (DAO) 中设置来自数据库的属性值,而使用 VO 模式,我们可以在 MVC 的控制器层中设置已在 DAO 层中设置的值。客户端可以访问 VO 对象,而不是他/她可以在 jsp 页面中迭代的 DTO。您可以说这两个层都存在关注点分离。
回答by Alireza Rahmani Khalili
DTOis a class representing some data with no logic in it. DTO's are usually used for transferring data between different applications or different layers within a single application. You can look at them as dumb bags of information the sole purpose of which is to just get this information to a recipient.
DTO是一个表示一些数据的类,其中没有逻辑。DTO 通常用于在不同应用程序之间或单个应用程序内的不同层之间传输数据。您可以将它们视为愚蠢的信息袋,其唯一目的是将这些信息提供给接收者。
On the other hand, Value Objectis a full member of your domain model. It conforms to the same rules as an Entity. The only difference between Value Object and Entity is that Value Object doesn't have its own identity. It means that two Value Objects with the same property set should be considered the same whereas two Entities differ even if their properties match.
另一方面,值对象是域模型的完整成员。它符合与实体相同的规则。值对象和实体之间的唯一区别是值对象没有自己的身份。这意味着具有相同属性集的两个值对象应该被认为是相同的,而两个实体即使它们的属性匹配也不同。
Value Objects do contain logic and, typically, they are not used for transferring data between application boundaries. Read more here
值对象确实包含逻辑,并且通常不用于在应用程序边界之间传输数据。在这里阅读更多
回答by Atul Jain
Value Object and Data Transfer Object are design pattern.
值对象和数据传输对象是设计模式。
- Value Object: Use when need to measure the objects' equality based on the objects' value.
- 值对象:当需要根据对象的值来衡量对象的相等性时使用。
Real world example is java.time.LocalDate
真实世界的例子是 java.time.LocalDate
public class HeroStat {
// Stats for a hero
private final int strength;
private final int intelligence;
private final int luck;
// All constructors must be private.
private HeroStat(int strength, int intelligence, int luck) {
this.strength = strength;
this.intelligence = intelligence;
this.luck = luck;
}
// Static factory method to create new instances.
public static HeroStat valueOf(int strength, int intelligence, int luck) {
return new HeroStat(strength, intelligence, luck);
}
public int getStrength() {
return strength;
}
public int getIntelligence() {
return intelligence;
}
public int getLuck() {
return luck;
}
/*
* Recommended to provide a static factory method capable of creating an instance
from the formal
* string representation declared like this. public static HeroStat parse(String
string) {}
*/
// toString, hashCode, equals
@Override
public String toString() {
return "HeroStat [strength=" + strength + ", intelligence=" + intelligence
+ ", luck=" + luck + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + intelligence;
result = prime * result + luck;
result = prime * result + strength;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
HeroStat other = (HeroStat) obj;
if (intelligence != other.intelligence) {
return false;
}
if (luck != other.luck) {
return false;
}
if (strength != other.strength) {
return false;
}
return true;
}
// The clone() method should not be public. Just don't override it.
}
- Data Transfer Object: Pass data with multiple attributes in one shot from client to server, to avoid multiple calls to remote server.
-数据传输对象:一次性将具有多个属性的数据从客户端传递到服务器,以避免多次调用远程服务器。
public class CustomerDto {
private final String id;
private final String firstName;
private final String lastName;
/**
* @param id customer id
* @param firstName customer first name
* @param lastName customer last name
*/
public CustomerDto(String id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}