5

通过智能对象,如果属性被更改,我会考虑任何知道其原始属性值的域对象。智能对象通常有一个基类并通过使用 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 并将它们放在我所有的派生域类中:

  • 常用属性(如 Id、Status...)
  • 对象状态跟踪(新的、修改的、未更改的)
  • 所有属性都会引发属性更改事件(INotifyProperyChanged 的​​实现)
  • 派生类可以自动序列化(虽然我很少发现这很有用)
  • 我可以拥有所有其他有用的行为 - 克隆/同步/IsPropertyDirty...

另一方面,POCO 非常简单,不依赖于任何基类。

现在我在这里有很多 POCO 称赞,因为:

  1. 它可以通过网络发送(通常以 JSON 格式发送到 Web 浏览器)
  2. 它是纯的

另一方面,我认为上述原因是谬误的,因为:

  1. DTO 用于电汇而不是域对象。当域对象序列化为 JSON 时封装数据的行为。
  2. 这种追求纯度接缝就像追求更加贫乏的领域模型,它没有逻辑,也没有任何智能附加在它上面。

带着这一切悲伤,我仍然喜欢那个 POCO,它让我很烦恼。你有什么意见?

4

2 回答 2

4
  • 常用属性(如 Id、Status...)

如果一个对象只是继承了一个定义 Id 属性的实体基类,我不会认为它是非 POCO。根据定义,实体具有身份,不会破坏 SRP,也不会通过导入第三方行为来改变对象的“纯度”。

状态更值得商榷,具体取决于您的意思,它可能确实会在您的对象中引入额外的责任,使其成为非 POCO。

您提到的大多数其他属性我认为应该由外部对象处理,而不是域对象本身。

  • 对象状态跟踪(新的、修改的、未更改的)

最好让您的域对象的更改跟踪专用代理来处理这个(这通常是 ORM 所做的)。

  • 所有属性都会引发属性更改事件(INotifyProperyChanged 的​​实现)

我认为这主要是与 UI 相关的东西,它们会进入您的演示对象而不是您的域对象。您可能不希望实体中的每个属性都是可观察的 - 要表示聚合中的更改,请改用领域事件。

  • 我可以拥有所有其他有用的行为 - 克隆/同步/IsPropertyDirty...

克隆通常可以是值对象的基本行为,而不会将它们视为非 POCO。除了您偶尔的特定领域需求外,克隆实体对我来说似乎没那么有用。Sync/IsPropertyDirty 看起来更像是版本控制/更改跟踪,应该委托给专门的对象。

这种追求纯度接缝就像追求更加贫乏的领域模型,它没有逻辑,也没有任何智能附加在它上面。

这里的问题都是关于“附加”的。并不是说符合 SRP 的对象不智能,而是它们不包含任何不是它们自然职责的智能对象。同样,POCO 并不愚蠢,它们只是没有移植外部来源行为的对象(3d 方库、框架扩展......)

于 2013-07-26T10:08:40.523 回答
1

我会坚持使用 POCO 内部模型,因为那些“智能对象”引入了如此多的复杂性。模型应该尽可能简单,只承载业务逻辑,而不是被可能有用的特性所污染。尤其是技术...

于 2013-07-26T09:23:47.130 回答