值对象模式与数据传输模式的区别

sur*_*uri 9 java design-patterns data-transfer-objects value-objects

在哪种情况下我可以在n层架构中使用这些设计模式?

Dmi*_*try 14

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

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

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

CustomerAndLastFiveOrders是DTO(已优化以避免多个网络呼叫)

客户是实体

MoneySKU是Value对象


Shi*_*ala 8

将DTO对象与值对象进行比较就像比较橙子和苹果.

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

在此输入图像描述

让我用例子解释一下,让我们先尝试先理解价值对象: -

值对象是一个对象,其相等性基于值而不是标识.

考虑下面的代码,我们创建了两个货币对象,一个是一卢比硬币,另一个是一卢比纸币.

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";
Run Code Online (Sandbox Code Playgroud)

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

因此,要么使用"=="运算符,要么使用"等于"方法,比较应评估为true.默认情况下,"=="或"equals"不会计算为true,因此您需要使用运算符重写和方法重写来获得所需的行为.您可以看到此链接解释如何实现相同的目标.

if (OneRupeeCoin==OneRupeeNote)
 {
 Console.WriteLine("They should be equal");
 }
if (OneRupeeCoin.Equals(OneRupeeNote))
 {
 Console.WriteLine("They should be equal ");
 }
Run Code Online (Sandbox Code Playgroud)

通常,价值对象是不可变性的良好候选者; 你可以从这里了解更多相关信息.您可以看到此视频,其中描述了如何创建不可变对象.

现在让我们试着了解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);
Run Code Online (Sandbox Code Playgroud)

因此,我们可以将Customer和Product类合并到一个类中,如下所示.

class CustomerProductDTO
{
  // Customer properties
        public string CustomerName { get; set; }
   // Product properties
        public string ProductName { get; set; }
        public double ProductCost { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在通过一个电话,我们将能够获得客户和产品数据.数据传输对象在两个场景中使用,一个用于改进远程调用,另一个用于展平对象层次结构; 您可以阅读本文,其中详细介绍了数据传输对象.

//Only one call
CustomerProductDTO cust = dal.getCustomer(1001);
Run Code Online (Sandbox Code Playgroud)

以下是完整的比较表.

在此输入图像描述


duf*_*ymo 2

我建议不要使用数据传输对象。在我看来,这是一种 EJB 1.0 反模式,被那些坚持层纯度的人赋予了价值。

值对象很有用。它通常是一个不可变的对象,比如金钱。它们应该是线程安全的。