存储库模式与“智能”业务对象

时间:2009-05-20 16:19:42

标签: data-structures architecture repository-pattern

在.NET(Winforms,WPF,ASP.NET)上创建大型企业级应用程序时,我看到了两个主要的“思想流派”。

有些人使用“存储库模式”,它使用知道如何获取,插入,更新和删除对象的存储库。这些对象相当“愚蠢”,因为它们不一定包含大量逻辑 - 例如它们或多或少是数据传输对象。

另一个阵营使用我所谓的“智能”业务对象,它们知道如何加载自己,并且它们通常具有Save(),可能是Update()甚至Delete()方法。在这里,你真的不需要任何存储库 - 对象本身知道如何加载和保存自己。

重大问题:您使用或更喜欢哪个?为什么?

您是否在所有应用中使用相同的方法,或者您在选择一种方法时是否有任何特定标准?如果是的话 - 这些标准是什么?

我不是想在这里开始一场火焰战 - 只是试图找出每个人对此的看法以及你的看法,以及为什么你使用一种(或两种)模式而不是另一种模式。

感谢任何有建设性的意见!

5 个答案:

答案 0 :(得分:38)

由于单一责任原则,我使用了存储库模式。我不希望每个单独的对象必须知道如何保存,更新,删除自己,这可以由一个单一的通用存储库来处理

答案 1 :(得分:15)

存储库模式不一定会导致愚蠢的对象。 如果对象在Save / Update之外没有逻辑,那么你可能在对象之外做了太多。

理想情况下,您永远不应该使用属性从对象获取数据,计算内容并将数据放回对象中。这是封装的突破。

因此,除非您使用简单的DTO对象进行CRUD操作,否则对象不应该是贫血。

然后将持久性问题与对象关注点分开是一种获得单一责任的好方法。

答案 2 :(得分:7)

以下是我遇到的两篇有趣的文章

Repository-is-the-new-singleton

The DAL should go all the way to UI

答案 3 :(得分:4)

我认为使用Repository模式与ActiveRecord模式最重要的副作用是测试和可扩展性。

如果没有ActiveRecord对象包含存储库本身,您如何在测试用例中隔离数据检索?你不能轻易伪造或嘲笑它。

除了测试之外,交换数据访问技术也会变得更加困难,例如从Linq-to-SQL到NHibernate或EntityFramework(尽管这种情况经常不会发生)。

答案 4 :(得分:1)

这实际上取决于应用程序的需求,但在处理复杂的业务模型时,我更喜欢ActiveRecord。我可以在一个地方封装(并测试)业务逻辑。

大多数ORM(EF,nHibernate等)都充当您的存储库。许多人认为在ORM之上的一个层将所有数据交互封装为存储库,我认为这是不正确的。根据Martin Fowler的说法,Repository将数据访问封装为集合。因此,为所有数据检索/变异提供单独的方法可能使用数据映射器或数据访问对象。

使用ActiveRecord,我喜欢拥有“实体”基类。我通常使用带有此基类的ORM(存储库),因此我的所有实体都具有GetById,AsQueryable,Save和Delete方法。

如果我使用更多的面向服务的体系结构,我将使用一个存储库(一个掩盖直接数据访问一个ORM)并直接在我的服务中调用它。