存储库模式缺少啥?你如何在现实世界中使用它?
Posted
技术标签:
【中文标题】存储库模式缺少啥?你如何在现实世界中使用它?【英文标题】:What am I missing with the Respository Pattern? How do you use it in the real world?存储库模式缺少什么?你如何在现实世界中使用它? 【发布时间】:2011-07-29 23:07:32 【问题描述】:我见过的每个存储库模式示例都处理一个非常简单的用例——一种对象类型和最基本的 CRUD 操作。然后,存储库通常会直接插入 MVC 控制器。
现实世界的数据访问并非如此。现实世界的数据访问场景可能涉及复杂的对象图和某种形式的事务包装器。例如,假设我想保存一个新订单。这涉及写入 Order、OrderDetails、Invoice、User、History 和 ItemStock 表。所有这些都必须进行交易、提交或回滚。通常我会传递诸如 IDbTransaction 和 IDbConnection 之类的东西,并将整个操作捆绑在一个服务层中。
存储库模式在哪里适合这个?我错过了什么(也许是工作单元)?有没有比通常的罐头博客 sn-ps 更现实的存储库示例?
欣赏任何光线。
【问题讨论】:
这不是几乎所有模式的真相吗?当他们离开玩具示例的安全上下文时,会出现问题吗? 这个问题不是在编程堆栈交换中得到更好的回答吗? 【参考方案1】:这是一个非常有争议的话题,但这是我根据自己的经验得出的结论。
Repository
在聚合根中工作。例如,如果OrderItem
始终作为Order
的一部分被检索,并且没有自己的外部命令的生命,那么它将由OrderRepository
加载,否则它将有自己的存储库。
UnitOfWork
是一个重要的概念。假设OrderItem
是一个聚合根并拥有自己的存储库。所以在创建订单时,OrderManager
会在using
块中创建一个UnitOfWork
工作,初始化OrderItemRepository
和OrderRepository
然后提交。
更新
是的,没错。想象一下——在我们的例子中是订单——正在插入一个订单。这需要控制交易并在同一交易中分别输入订单和订购商品。这无法在存储库级别进行管理。这是存在UnitOfWork
概念的唯一原因,该概念被传递到存储库,因此它不拥有或初始化它。 UnitOfWork
通常是在业务层创建的。
【讨论】:
好的,所以你在这里暗示了一些事情:有有更高级别的服务/管理器类型类来收集和协调事务操作?【参考方案2】:像 Hibernate 这样的 O/R-Mapper 基本上实现了对象图的存储库模式,同时完全支持事务。它通常是一个有漏洞的抽象,但它肯定可以在复杂的现实世界场景中工作。
【讨论】:
不太正确...我正在使用nhibernate
但我正在实现自己的存储库。【参考方案3】:
如果您需要一个完整的、广泛使用的存储库模式示例,请查看Cocoa's Core Data 我意识到它不在您注意到的编程语言领域。但请注意,它不是 O/R 映射器。它是对象存储的完整抽象。没有要执行的 Sql 语句,虽然您可以选择使用的外部存储的格式,但您从不直接与其交互。
【讨论】:
【参考方案4】:我喜欢将存储库视为另一层抽象。只有在实现成本低于不执行的成本(代码维护、支持、增强等)时,您才应该添加抽象层。
请记住,purpose of the repository pattern 是将检索数据 (CRUD) 并将其映射到实体模型的逻辑与作用于模型的业务逻辑分开。这通常最终在现实世界中做/看起来是某种形式的业务实体,它抽象了底层物理数据模型。
就您的交易问题而言,是的,这更多地与Unit of Work pattern 相关。由于您提到了服务,我鼓励您不要将您的连接传递给您的各种数据访问类/方法,而是允许 WCF 使用自动登记为您管理事务。 Here is an extract 的 Juval Lowy's WCF book(强烈推荐)解释了这种事务管理方法的方式和原因。
因此,为了回答您的问题,存储库模式适合作为抽象物理数据模型并将 CRUD/映射与业务逻辑分离的一种方式。
【讨论】:
以上是关于存储库模式缺少啥?你如何在现实世界中使用它?的主要内容,如果未能解决你的问题,请参考以下文章
如何将缺少的 svn:author 批量添加到存储库或转储中?