域对象扩展数据传输对象



我是DDD和OO原则的新手,对不起,我的知识很差。

我有客户DTO客户类。

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

使用 DTO 的主要目的是将其传递给 View。我已经在客户类中扩展了它,以免具有重复的属性。

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

我已经阅读了有关AutoMapper的信息,但我想知道是否有替代解决方案。

非常感谢任何形式的帮助。

我个人从未见过这种方法。使用 DTO 的原因是将关注点分开 DAL 和业务层。它允许业务层和 DAL 按照自己的节奏进行更改,而副作用最小。您所要做的就是更改 DTO 和 DO 之间的映射。如果您从 DTO 继承了您的 DO,那么即使拥有 DTO 又有什么意义呢?

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

PS不要害怕自动映射器。它相对易于使用。

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

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

扩展答案:

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

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

领域模型 - 这里的关键词是"模型"是解决其问题的域的抽象。从面向对象的角度来看,它是简单的类,如果将其分解,它将是纯数据(DTO)和纯无状态行为(DDD术语中的服务或域服务)。

现在让我们以 MVVM 模式为例,特别是它是 VM 部分。 视图模型 - 这里的关键词再次是"模型"是解决其问题的视图的抽象。人们实现它的方式有很多,有些包装域对象,一些进行转换,一些包装 DTO。这里的重点是视图模型是视图的域模型,它与任何模型几乎相同。那为什么人们限制实现域模型的方式。

现在回到DTO和域模型。正如我上面所说,我们可以将域对象分解为 DTO 和服务。让我们考虑一下,我们将域对象视为DTO的行为包装器(就像MVVM经常做的那样)。它引领我们的地方:

  • 首先,我们打破 OO 封装。这很糟糕,因为它可以防止我们的对象数据被错误使用。有人可以直接获取我们的域对象数据(DTO)操作它,并将我们的模型置于无效状态。这是巨大的。
  • 我们可以轻松地传输我们的对象抛出边界、Web 服务、序列化、克隆,我们可以分离出数据部分,并将其提供给我们的数据存储或 Web 服务。这对于分布式系统来说是巨大的。

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

现在关于重用DTO,继承与组合。有人说:比起继承,我个人确实遵循这个规则。但你需要分析你的具体情况。规则说"宁愿"不服从。

原文:

虽然我个人并不经常看到这种方法,但我认为这种方法被低估了,它可能非常好。

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

瑞安·班纳特(Ryan Bennet)在回答中写道:

现在可能很容易,但这可能是一个维护噩梦 前途。

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

代码不是你刻在石头上永远不要碰的东西,当你需要的时候,你可以重构,引入DTO,使用自动映射器或其他任何东西。

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

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

忽略实际持久化数据的表的外观,或者是否使用 TPH、TPT 或 TPC,假设您有 DO 类

Vehicle
Car : Vehicle
Boat : Vehicle

你不能有Car : CarDto, Vehicle.如果您的项目足够复杂,可以在 DO 类之间进行任何继承,那么这本身就是一个非常有说服力的论点。

最后,我想补充一点,在继承与组合之间进行选择时,您会考虑"是a"与"具有a"。那么,"汽车是CarDto"还是"汽车是车辆"哪个更有意义?后者是海事组织。

最新更新