【发布时间】:2013-07-26 00:46:27
【问题描述】:
通过智能对象,如果属性被更改,我会考虑任何知道其原始属性值的域对象。 智能对象通常有一个基类并通过使用 GetPropertyValue/SetPropertyValue 方法来实现属性。 另一方面,POCO 对象通常没有基类并实现简单的属性。
public class SmartObject : BaseDomainObject
{
public int id
{
get { return (int)this.GetPropertyValue("Id"); }
set { this.SetPropertyValue("Id", value); }
}
}
public class POCO
{
public int id { get; set; }
}
我喜欢智能对象,因为它为我做了很多艰苦的工作。我可以轻松地将所有这些有用的功能添加到 BaseDomainObject 并将它们包含在我所有派生的 Domain 类中:
- 常用属性(如Id、Status...)
- 对象状态跟踪(新的、修改的、未更改的)
- 所有属性都会在属性更改时引发事件(INotifyProperyChanged 的实现)
- 派生类可以自动序列化(虽然我很少发现这很有用)
- 我可以拥有所有其他有用的行为 - 克隆/同步/IsPropertyDirty...
另一方面,POCO 超级简单,不依赖于任何基类。
现在我在这里得到了很多 POCO 的赞美,因为:
- 可以通过网络发送(通常以 JSON 格式发送到 Web 浏览器)
- 它是纯粹的
另一方面,我认为上述原因是谬误的,因为:
- DTO 用于电汇而不是域对象。将域对象序列化为 JSON 时封装数据的行为。
- 这种对纯度的追求与对更虚弱的领域模型的追求相得益彰,它既没有逻辑也没有任何智能。
尽管如此悲伤,我仍然喜欢那个 POCO,它让我很烦。你有什么意见?
【问题讨论】:
-
如果您正在努力实现丰富的域模型,请不要因技术基础架构问题而污染它。您提到的所有事情——状态跟踪、属性更改事件、序列化——这些事情都与域无关。他们没有将业务领域的复杂性编码到模型中。
-
另一方面,POCO 也没有将域复杂性编码到模型中。所以按照 DDD 标准,这两种方法都很差。
-
@MattDavey 我同意你的第一条评论,但我不确定后者。 POCO != 贫血,如果这就是你的意思。除了数据之外,普通的旧面向对象确实包括行为,如果适用,还包括域行为。
-
@guillaume31 你是对的。最近似乎 POCO 已成为仅包含 getter/setter 的对象的同义词(导致与 DTO 对象混淆)。我们应该记住POCO的真正含义,您在问题的最后一句话中解释了这一点。
标签: .net architecture domain-driven-design domain-model anemic-domain-model