域对象扩展了数据传输对象

时间:2012-06-26 13:22:39

标签: .net oop domain-driven-design data-transfer-objects

我是DDD和OO原则的新手,抱歉我的知识不足。

我有 CustomerDTO 客户类。

我将所有字段和属性存储在 DTO 类中,并将其用作客户类的基类

使用 DTO 的主要目的是将其传递给查看。我已经在客户类中扩展了它,不会重复属性。

这是正确的方法还是有更好的OO解决方案?

我已经阅读过AutoMapper,但我想知道,如果有其他解决方案。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:6)

我个人从未见过这种做法。您使用DTO的原因是分离DAL和biz层之间的关注点。它允许业务层和DAL按照自己的步调进行更改,并且副作用最小。您所要做的就是更改DTO和DO之间的映射。如果您从DTO继承了DO,那么即使拥有DTO也是如此?

快速回答:不要从DTO继承您的DO。现在可能很容易,但它可能是未来的维护噩梦。

PS不要害怕Automapper。它相对容易使用。

答案 1 :(得分:2)

这是一个坏主意。这有两个原因(可能还有一些)原因:

  • 域对象专门用于交易。他们不应该提供所有财产的公共访问权限。它们应该只包含提供行为目的的属性。 DTO有一个目的:向消费者提供数据(例如UI / Web服务/消息系统)。例如,客户DTO可能包含一个属性,该属性提供客户已下达的订单数量以及他们花费的总金额。但是,在域方面,客户汇总可能不会包含任何此类信息,因为此订单信息存储在专门为订单交易量身定制的单独订单汇总中。
  • DTO是愚蠢的POCO,只有一堆吸气剂& setter方法。允许域对象在其所有属性上具有setter是非常糟糕的做法。操作应该是原子操作,并由具有描述其意图的显式名称的方法提供。 this问题的答案解释了这一点。

答案 2 :(得分:0)

扩展答案:

让我们试着分析一下这种情况,不要盲目地说没有人做这样的事情。

DTO - 它的结构只包含数据并在边界之间传输。

域模型 - 这里的关键词是'模型'是你域的抽象,解决了它的问题。从OO视图来看,这是一个简单的类,如果你将它分开,它将是纯数据(DTO)和纯无状态行为(DDD术语中的服务或域服务)。

现在让我们以MVVM模式为例,特别是它的VM部分。视图模型 - 这里的关键词是'模型'是一个解决它的问题的视图的抽象。人们实现它的方式很多,有些包裹Domain Objects,有些包含转换,有些包装DTO。这里的观点是视图模型是视图的领域模型,它与任何模型几乎相同。那么为什么人们会限制实现域模型的方式。

现在回到DTO和Domain Model。如上所述,我们可以将域对象分解为DTO和服务。让我们考虑将Domain对象视为DTO的行为包装(就像MVVM一样)。它引领我们的地方:

  • 首先我们打破OO封装。这很糟糕,因为它可以防止我们的对象数据被错误使用。有人可以让我们的Domain对象数据(DTO)直接操作它并将我们的Model置于无效状态。这太棒了。
  • 我们可以轻松地转移对象投射边界,Web服务,序列化,克隆,我们可以分离数据部分,并将其提供给我们的数据存储或Web服务。这对分布式系统来说非常重要。

让我们继续,打破封装是一个严重的问题。我们需要的是一种方法来保证我们的域对象数据不会被直接操作,只有域对象才能操纵它。我们可以通过使DTO不可变,只读对象,当它在域对象之外时实现这一点。

现在关于重用DTO,继承与组合。有人说:更喜欢作文而不是继承,我个人也遵循这条规则。但是你需要分析你的具体情况。规则说“更喜欢”不遵守。

Original Asnwer:

虽然我没有经常亲眼看到这种方法,但我认为这种方法被低估了,而且可能非常好。

我多次看到这样的问题,并且所有答案都是,不要这样做,因为没有人这样做。不要害怕尝试。

瑞安班纳特在回答中写道:

  

现在可能很容易,但它可能是维护中的噩梦   将来

嗯,这是真的,但是如果没有未来或它的小项目,我会坚持YAGNI,TDD和敏捷规则,并做最少的工作来完成这项工作。

代码不是你刻在石头上的东西,永远不会触摸,当你需要时你可以重构,引入DTO,使用自动映射器等等。

答案 3 :(得分:0)

老问题,我在这里也喜欢其他几个答案,特别是关于将DAL与业务层分开。但是,我想提一下当DO类继承自DTO类时可能遇到的具体问题。

在.NET语言(如C#和VB)中,您不能拥有真正的多重继承。那是一个类不能扩展两个基类。因此,如果您的DO类已经扩展了DTO基类,那么您已经排除了DO类和另一个DO类之间继承的可能性。

忽略实际持久保存数据的表格或者是否使用TPH, TPT, or TPC,假设您有DO类

Vehicle
Car : Vehicle
Boat : Vehicle

你不能拥有Car : CarDto, Vehicle。如果你的项目很复杂,在DO类之间有任何继承,那么这本身就是一个非常引人注目的论点。

最后,我想在继承与构图之间进行选择时添加一个,你认为"是" vs."有一个"。更有意义的是:" Car是CarDto"或者"汽车是一辆车"?后者IMO。