模型视图控制器 – 存储库模式:什么是“正确的大小”?

前端之家收集整理的这篇文章主要介绍了模型视图控制器 – 存储库模式:什么是“正确的大小”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在为一个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; }
}

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

1存储库

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

2存储库

另一个设计将有一个“时间卡”存储库和另一个“考勤”记录库.这具有的优点是,例如“时间卡”的业务规则自己在一个地方.但是,我也想有一种方法获取所有时间记录的列表,不管类型如何.目前还不清楚哪种存储库用于这种情况.都?

3存储库

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

混合动力

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

其他?

我错过了什么?一个设计的另一个引人注目的论据?

解决方法

至少我不知道存储库是业务规则的地方.他们只是一个模仿收藏的门面;他们基本上是纯粹的数据访问(如果这是工作,你可能不会持有存储库的任何东西).因此,独立的存储库不应被视为“业务规则”的原因.
>如果您的域对象真的是单独的对象,那么您应该有单独的存储库.记住一个存储库:它是一个立面.它将一个集合模拟到您的域.看到这里有一个很好的博客文章存储库: http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx

仓库是一个门面;抽象.

那个说…我不认为你有独立的对象.这里有一些与存储库无关的问题,以及域和域的设计.两种类型的“计时卡”实际上是两个不同的东西,还是真的一样?

你说,“但是我觉得有点奇怪,我可以从两个不同的仓库获得同样的记录.”

这告诉我,他们实际上是相同的数据,用不同的方式表达.有办法处理这个问题.

如果真的是这样,那么你在这里就是一个普通基类的子类(例如,可以使用NHibernate来优化DB中的模型,可以在DB中建模).

我会给你一个我正在研究的项目的例子.我有一个叫“广播”的东西.这是一个基础课抽象.无法实例化.我有这个类的两个具体具体类型:DeviceBroadcast和FileBroadcast.一个从设备(如DirectX捕获卡)流式传输音频/视频,一个从文件源(如.mp3)流式传输音频/视频.

我有一个存储库返回一个Broadcast对象.我可以将其转换为FileBroadcast来处理有关FileBroadcast的特定信息,或者因为同样的原因我可以转换为DeviceBroadcast(如果是该类型).广播不能同时是FileBroadcast和DeviceBroadcast类型.它必须是一个或另一个.

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

广播基类具有两个子类使用的常见方法(如GetCommand()方法,它返回一个特定的命令行参数来启动VLC进程).子类必须覆盖并实现该方法,因为它是抽象的.以这种方式,FileBroadcast所特有的“业务逻辑”包含在FileBroadcast类中. DeviceBroadcast唯一的“业务逻辑”包含在DeviceBroadcast类中.任何两者共同的逻辑都包含在超类“Broadcast”中.

你似乎在这里有一个类似的情况,这就是为什么我正在分享我的设计.我认为这可能会为你服务.

最重要的是考虑您的域名和数据.如果您要通过单独的存储库获取重复的数据,那么您需要更多地考虑如何设计域.不要让用户指定您的域名设计.他们从他们的角度知道领域.所有你需要做的是能够以他们理解的方式向他们呈现数据.这并不意味着你必须有一个坏的设计;你可以在幕后有一个很好的设计,因为你的代码是必须使用该域的东西.

原文链接:https://www.f2er.com/html/230911.html

猜你在找的HTML相关文章