代码之家  ›  专栏  ›  技术社区  ›  Craig Stuntz

存储库模式:什么是“正确的大小”?

  •  14
  • Craig Stuntz  · 技术社区  · 17 年前

    我正在为MVC应用程序构建一些存储库,并试图提出在存储库之间划分责任的正确方法。在大多数情况下,这是显而易见的。但有一个特殊的情况,我不确定正确的答案是什么。

    此应用程序的用户需要为其员工跟踪多种类型的时间。为了简单起见,让我们只考虑两个。我称之为“考勤卡”和“出勤率”。这两者之间差异的确切性质并不重要,但你应该注意,最终用户认为它们是完全独立的数据。不过,我认为,他们认为这些数据完全独立的原因是,他们过去从未真正有机会看到它们在一起。这两种类型的记录在编辑记录方面几乎有完全不同的业务规则,但一般来说,它们也是员工在特定时间所在位置的记录。这两种类型的时间记录有很多共同的属性,例如总小时数和收集时间的员工。这两种类型都有一些属性,这些属性对于单个类型来说是完全唯一的。我们将这些“额外”属性保存在另一种类型的实例中。因此,总体结构如下:

    class TimeRecord 
    { 
        Person Employee { get; set; }
        TimeSpan? Hours { get; set; }
    }
    
    class TimeCardData
    {
         TimeRecord Record { get; set; }
         TProperty TimeCardProperty  { get; set; }
    }
    
    class AttendanceData
    {
         TimeRecord Record { get; set; }
         TProperty AttendanceProperty  { get; set; }
    }
    

    所以问题是, 这里需要多少个存储库?

    只有一个存储库的设计将公开在一个列表中返回“考勤卡”、“出勤”记录或这两种类型的方法。这对存储库的客户端来说相当方便,但在我看来,有成为一个非常胖的类的真正危险。我认为,仅仅用于“考勤卡”的存储库已经成为系统中最大的存储库之一,即使由于涉及复杂的业务规则而不处理“考勤”。

    2个存储库

    3个存储库

    一种设计是,一个存储库用于“考勤卡”,另一个存储库用于“出勤”记录,第三个存储库提供所有时间记录的只读列表。与2存储库设计一样,这具有的优点是,例如“考勤卡”的业务规则本身就在一个地方。现在很清楚在哪里可以获得合并列表。但我觉得有点奇怪,我可以从两个不同的存储库中获得相同的记录。

    混合

    混合方法将使用单个存储库,但将任何业务规则代码(包括记录选择)移动到单独的类型中。在这个例子中,一个单一的“时间记录存储库”将聚合“考勤卡”和“出勤”时间的业务规则实现类的实例。我认为这是我现在最喜欢的方法。

    其他?

    1 回复  |  直到 16 年前
        1
  •  18
  •   Chris Holmes    17 年前
    1. 如果你的域对象是真正独立的对象,那么你应该有单独的存储库。记住什么是存储库:它是一个外观。它模拟了您域名的集合。在这里看到一篇关于仓库的非常好的博客文章: http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx

    存储库是一个门面;抽象。

    你说, “但我觉得有点奇怪,我可以从两个不同的存储库中获得相同的记录。”

    这告诉我,他们实际上是

    如果真是这样,那么你在这里得到的是一个公共基类的子类(例如,可以在数据库中很容易地建模,并使用NHibernate优雅地处理)。

    我有一个返回Broadcast对象的存储库。我可以将其转换为FileBroadcast来操纵有关FileBroadcast的特定信息,或者出于同样的原因,我可以将它转换为DeviceBroadcast——如果它是那种类型的话。广播不能同时是FileBroadcast和DeviceBroadcast类型。它必须是其中之一。

    在数据库中,我将通用广播参数存储在broadcast表中,然后将特定于文件的属性存储在FileBroadcast表。DeviceBroadcast表也是如此;分开。然而,当我通过存储库查询时,我只想要广播。这是我的根聚合对象,因此也是我的存储库。

    你似乎也有类似的情况,这就是我分享我的设计的原因。我认为它可能对你很有用。