存储库模式与“智能”业务对象 [关闭]
Posted
技术标签:
【中文标题】存储库模式与“智能”业务对象 [关闭]【英文标题】:Repository pattern vs. "smart" business objects [closed] 【发布时间】:2010-10-27 16:44:14 【问题描述】:在 .NET(Winforms、WPF、ASP.NET)上创建大型企业级应用程序时,我看到了两个主要的“思想流派”。
有些人使用“存储库模式”,它使用知道如何获取、插入、更新和删除对象的存储库。这些对象相当“愚蠢”,因为它们不一定包含大量逻辑 - 例如。它们或多或少是数据传输对象。
另一个阵营使用我所谓的“智能”业务对象,它们知道如何加载自己,它们通常有一个 Save()、可能是 Update() 甚至是 Delete() 方法。在这里,您真的不需要任何存储库 - 对象本身知道如何加载和保存自己。
最大的问题是:您使用或喜欢哪个?为什么?
您是否在所有应用中都使用相同的方法,或者您是否有任何特定标准来选择一种方法而不是另一种方法?如果是这样 - 这些标准是什么?
我不是想在这里发起一场激烈的战争——只是想了解每个人对此的看法和你的看法,以及为什么你使用一种(或两种)模式而不是另一种模式。
感谢您的任何建设性意见!
【问题讨论】:
【参考方案1】:由于单一职责原则,我使用存储库模式。我不希望每个单独的对象都必须知道如何保存、更新、删除自己,因为这可以由一个通用存储库处理
【讨论】:
在这种情况下,一个通用存储库需要知道如何加载所有类型的对象。 并且因为它是通用的,它可以处理加载所有类型的对象。也使单元测试更简单 我也喜欢存储库风格,因为数据传输对象更灵活。您可以在任何地方使用它们,不依赖于框架、层等。它们仅代表概念、模型。如果你想在模型和 BD 之间架起一座桥梁,你可以构建持久层。您希望在模型和构建 UI 的用户之间架起一座桥梁。您想要计算事物,实现用例,构建业务逻辑。所有这些都与仅与业务概念本身无关的简单模型对象有关。【参考方案2】:存储库模式不一定会导致愚蠢的对象。 如果对象在保存/更新之外没有逻辑,那么您可能在对象之外做了太多事情。
理想情况下,您永远不应该使用属性从对象中获取数据、计算事物并将数据放回对象中。这是封装的突破。
所以对象不应该是贫血的,除非你使用简单的 DTO 对象和 CRUD 操作。
然后将持久性关注点与对象关注点分开是拥有单一职责的好方法。
【讨论】:
不,当然 - 我的 busobj 并不完全“愚蠢” - 我只是说“愚蠢”,因为他们不知道如何加载和保存自己 - 他们确实有其他功能,显然:-) 这是理智的设计。我个人认为“bo 知道加载自己”是不雇用开发人员的理由 - e 显然从未听说过职责分离,也从未见过适当封装的 DAL。 你用过CSLA吗?它在我们使用它的涉及 N 层部署的项目中运行良好。【参考方案3】:这是我遇到的两篇有趣的文章
Repository-is-the-new-singleton
The DAL should go all the way to UI
【讨论】:
【参考方案4】:我认为使用存储库模式与ActiveRecord 模式相比最重要的副作用是测试和可扩展性。
如果您的 ActiveRecord 对象本身不包含存储库,您将如何隔离测试用例中的数据检索?你真的不能轻易伪造或嘲笑它。
除了测试之外,更换数据访问技术也会变得更加困难,例如从 Linq-to-SQL 到 NHibernate 或 EntityFramework(尽管这并不经常发生)。
【讨论】:
【参考方案5】:这确实取决于应用程序的需求,但是在处理复杂的业务模型时,我更喜欢 ActiveRecord。我可以在一个地方封装(和测试)业务逻辑。
大多数 ORM(EF、nHibernate 等)都用作您的存储库。许多人认为 ORM 之上的一层将所有数据交互封装为 Repository,我认为这是不正确的。根据 Martin Fowler 的说法,存储库将数据访问封装为一个集合。因此,为所有数据检索/变异提供单独的方法可能是使用数据映射器或数据访问对象。
使用 ActiveRecord,我喜欢有一个“实体”基类。我通常在这个基类中使用 ORM(存储库),所以我的所有实体都有 GetById、AsQueryable、Save 和 Delete 方法。
如果我更多地使用面向服务的架构,我将使用存储库(一个隐藏直接数据访问的存储库或 ORM)并直接在我的服务中调用它。
【讨论】:
以上是关于存储库模式与“智能”业务对象 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章