【问题标题】:Domain object design领域对象设计
【发布时间】:2012-07-20 14:50:14
【问题描述】:

在设计你的领域模型时,应该坚持代表问题领域的东西,并且领域模型不应该包含审计信息。

所以,如果我在设计一只猫,它可能看起来像这样:

public Cat {
    private Color furColor;
    private Color eyeColor;
    private boolean isDeclawed;
    etc...
} 

我不应该有像“updateDate”和“createTime”这样的属性,对吗?

现在,如果 Web 应用程序要在屏幕上显示一张猫的表格,您可能会有类似的内容:

名称眼睛颜色爪?最近更新时间 ------ --------- ------ ------------ 蓬松的绿色 No 10/31/2012 ETC...

那么,如果您不在域模型中保留上次更新时间,那么如何(正确地)将该数据获取到页面?

显然,我可能有一个设计不佳的域模型,但我想做得更好。

我曾考虑创建一个接受泛型的对象,以便我可以保持我的域模型的原始状态。 即

public PersistableObject<T,K> {

    private T domainObject;
    private Date updateDate;
    private User updateUser;

    getters, setters, etc...
}

但是,我恐怕会遇到一些问题。

我在“域模型”和“更新日期”等方面进行了很多搜索......但我认为我错过了正确的术语。

有人能指出我正确的方向吗?

【问题讨论】:

  • 深入挖掘,为什么需要审计线索?为什么需要显示“上次更新”列?

标签: architecture domain-driven-design audit


【解决方案1】:

在你的场景中,我不确定我是否同意第一句话。如果您的域的一般用途包括需要显示这些日期,那么它们可能(并且可能应该)是您的正常域对象的一部分。

如果你想清理你的域对象,你可以简单地创建一个接口来保存这些公共字段。

public interface ITrackedObject
{
    DateTime LastUpdated { get; set; }
    //etc....
}

public class Cat : ITrackedObject
{
    public DateTime LastUpdated { get; set; }
    //....
}

【讨论】:

  • 那么,如果您要拥有一个没有自己的数据库的 PhoneNumber 类,它也会扩展 TrackedObject?它真的不需要 DateTime 属性,对吗?
  • 您的所有域对象都不需要扩展TrackedObject...只有那些被跟踪的对象。要使其正常工作,需要在域内设置 LastUpdated 属性。它应该与持久性无关(因此数据库列中没有“默认”值等)。
  • 我喜欢这个策略,但是我会使用接口ITrackedObject,否则如果你的超类没有实现TrackedObject,你就不能再从Animal继承了
  • @Aphelion - 很好,我也在考虑同样的问题,尽管每个子类都需要实现 LastUpdated 属性。只是想避免这种情况。我认为这取决于特定的对象模型,尽管您的方法显然会更灵活。
  • 那么,为什么带有泛型的模型不起作用?我可以将 PersistableObject 传递给我的 DAO,同时仍然有一个原始的 Cat 模型。
【解决方案2】:

我会尽力而为。我认为您可能将对象与记录混合在一起。最后更新的日期不是猫的更新时间,而是记录的更新时间。在 OO 中,很自然地认为您可以将关于该对象的所有内容封装在一个对象中。但是一个对象本身并不表达任何上下文。即使在你的猫中,你也有一个颜色类型,如果你没有办法获得 rgb 或 cmyk 值,它本身就什么都不是。

在 OO 的第一天展示的第一个示例讲师是猫是动物,动物是生物等等。没有理由不能在您的域对象中进行最后一次修改,甚至最后一次更新在大多数情况下都是一个很好的调用。但是,如果您可以分离和建模对象将如何与其他对象交互,以及如果它们定义太多,它们将如何受到限制(是的,我说限制是因为它已经决定了很多事情)。我并不是要建议过度考虑对象的重用,但对于一个应该能够在 10 英尺或 10000 英尺视图中提供上下文和意义的模型来说,适当的关系非常重要。

我在平台研发工作了近 9 年,建模和开发平台跨越了很多年才完成。总是杀死我们的一件事是让一两个 ia-a 和 has-a 关系倒退。这将使模型变得无用,此时还不如拥有一个包含 200 列的平面表,但在大型甚至小型模型中重构几个关系永远是一个重大挫折。对象不是记录,甚至不是类,它们是赋予数据意义的东西。

简而言之,MyBizObject 扩展了 MyBizRecord 它在所有书籍中的推荐方式,但 MyBizProduct ... 扩展 MyBizMaterial 数组 MyBizRecord[] changeHistory; …… 功能强大得多,如果有一天您需要将 MyBizOrders[] 添加为历史记录,您将不必重新设计整个模型和工厂。我敢肯定这不是您期望阅读的内容,但我希望它能让车轮转向您正在寻找的答案。

【讨论】:

  • 它确实让车轮转动。感谢您抽出宝贵时间来回答。
猜你喜欢
  • 2011-05-26
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 2014-03-09
  • 2015-02-27
  • 2013-12-07
  • 1970-01-01
  • 2012-08-24
相关资源
最近更新 更多