回答

2

我会建议针对数据传输对象。这是一个EJB 1.0反模式,在我看来,坚持图层纯度的人给予了价值。

值对象是有用的。它通常是一个不变的对象,像Money。他们应该是线程安全的。

+0

为什么当它们不可变时它们必须是线程安全的? –

+3

不可变IS线程安全。 – duffymo

+0

对不起。我以为你说过我们必须让它安全。 –

11

DTO是您可以在系统的边界处使用的对象。例如,当您有一个SOAP Web服务并且您想要返回响应时,您将使用DTO。比实际的XML更容易处理,必须通过电线返回。 DTO经常由工具生成,例如基于WSDL。 DTO常常根据服务消费者的需求量身定制,并可能受性能要求的影响。

价值对象另一方面住在系统的核心。它捕获了一些业务逻辑和可能的格式规则。它使您的代码更安全,更具表现力。它还处理“原始痴迷”反模式。很好的例子是使用类“SocialSecurityNumber”而不是字符串。或者钱而不是小数。这些对象应该是不可变的,因此它们看起来更像是基元,并且可以在不同线程之间轻松共享。

例如,在假设的 '客户订单' 系统:

CustomerAndLastFiveOrders是DTO(优化,以避免多个网络电话)

客户是实体

SKU是价值对象

2

值对象是封装为对象时有用的东西,但它没有标识。将它与一个实体进行比较,该实体具有身份。因此,在订单处理系统中,Customer或Order或LineItem是指向特定人员或事物或事件的概念,因此它们是实体,其中值对象类似金钱量,并没有自己独立存在。例如,对于部分应用涉及计算如何在不同账户之间划分支付的系统,我创建了一个不可变的Money对象,该对象具有一个分割方法,该方法返回一个Money对象数组,平均分割原始对象的数量,分配数量的代码在写jsp的人可以使用它的地方是非常方便的,并且他们不必将jsp与非表示相关的代码混淆起来。

数据传输对象是用于将事物捆绑在一起以便跨应用程序层或层发送的包装器。这个想法是,你想通过设计发送大量信息的方法来减少网络往返流量。

2

有几个很好的答案在这里,但我会添加一个捕捉到一个关键的区别:

值对象没有身份。这是包含值对象的两个实例之间的任何比较应表明它们是相等的。数据传输对象虽然只用于保存值,但确实有身份。比较具有相同值但独立创建的DTO的两个实例并不表示它们是平等的。

实施例:

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 

及其稍微难以执行在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; 
    } 
} 
6

比较DTO对象与值对象就像比较桔子和苹果。

他们服务完全不同的情况。 DTO定义了数据如何在图层之间传输的对象/类结构,而值对象在比较值时定义了相等的逻辑。

enter image description here

让我举例说明你,让我们先试着先了解价值的物品: -

值对象是一个对象,其平等基础上的价值,而 不是身份。

考虑我们创建了一个钱两个物体下面的代码是一个硬币卢比,另一个是1个卢比纸币。

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"; 

现在,当您比较上述对象时,下面的比较应评估为真,因为1卢比钞票等于现实世界中的1卢比硬币。

因此,无论您是使用“==”运算符,还是使用“Equals”方法,比较结果都应为true。默认情况下,“==”或“equals”不会计算为真,因此您需要使用运算符重写和方法重写来获得所需的行为。你可以看到这个link,它解释了如何实现相同。

if (OneRupeeCoin==OneRupeeNote) 
{ 
Console.WriteLine("They should be equal"); 
} 
if (OneRupeeCoin.Equals(OneRupeeNote)) 
{ 
Console.WriteLine("They should be equal "); 
} 

正常值对象是不变性的良好候选者;你可以从here了解更多关于它的信息。您可以看到this video,它描述了如何创建不可变对象。

现在,让我们试着去了解DTO: -

DTO(数据传输对象)可以简化移动层之间 数据传输的数据容器。

它们也被称为转移对象。 DTO仅用于传递数据并且不包含任何业务逻辑。他们只有简单的制定者和获得者。

例如,考虑下面的调用,我们正在进行两个调用,一个用于获取客户数据,另一个用于获取产品数据。

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); 

所以我们可以将Customer和Product类结合到一个类中,如下所示。

class CustomerProductDTO 
{ 
    // Customer properties 
     public string CustomerName { get; set; } 
    // Product properties 
     public string ProductName { get; set; } 
     public double ProductCost { get; set; } 
} 

现在只需一个电话,我们就可以同时获得客户和产品数据。数据传输对象在两种情况下使用,一种用于改善远程调用,另一种用于扁平化对象分层结构;你可以阅读这个article,它更详细地解释了数据传输对象。

//Only one call 
CustomerProductDTO cust = dal.getCustomer(1001); 

下面是完整的比较表。

enter image description here

0

数据传输对象是用来设置其从数据库来在数据访问层(DAO)的属性值,其中作为使用VO图案我们可以在在DAO已经设置MVC的控制器层中设置的值层。客户端可以访问VO对象而不是他/她可以在jsp页面中迭代的DTO。 你可以设置这两个层都有一个关注点。

相关问题