使用LINQ的多个或单个存储库

时间:2009-05-26 11:12:06

标签: asp.net-mvc linq tdd

我一直在阅读Professional ASP.NET MVC 1.0书中的第11章(可测试设计模式)。在本章的示例中,数据访问被分成许多存储库:IOrderRepository,IProductRepository等。这些都是有意义的:单个数据库的单个存储库。

但是,当您考虑表之间的链接时,这会对我造成一些影响:订单包含许多产品。当Order类由LINQ-to-SQL创建时,订单类将具有Products集合,该集合枚举与该订单相关的所有产品。因此,通过使用此集合,我们将绕过ProductsRepository。

因此,在模拟时,我不仅要模拟OrderRepository和ProductRepository,我还必须在返回的Order对象中填充Products集合。这意味着模拟的OrderRepository必须知道模拟的ProductsRepository等等。

忽略LINQ如此友好地为我创建的这些集合似乎是浪费,所以我的问题是,在这种情况下,单个存储库不会更有意义吗?

2 个答案:

答案 0 :(得分:12)

你的问题描述是一个典型的教科书例子,当过多的关于'这是好的,那是坏'的blabla成为开发人员以创建方式创建软件而不是查看手头的问题并创建软件的原因解决这个问题。

例证:您的问题描述不是您需要解决的问题:您有一个为您的客户创建的应用程序,这是您应该解决的问题。如果你选择的工具让你的生活变得艰难,那么就把它们踢出去并使用有效的东西:如果嘲弄不起作用,为什么还要费心呢?哦,因为有人说如果你不嘲笑你的软件会很糟糕吗?为什么呢?

你在这里和那里找到了一些DDD的东西,但是你错过了一些重要的部分:产品是一个聚合根。这意味着您应该从自己的存储库中获取产品。是的,这减轻了模型中的导航功能,但这对你来说是DDD,如果你严格按照埃文斯的书的第二部分所指示的那样创建存储库。但是......你呢?

如果您无法回答为什么Product有自己的存储库,但您可以从Order导航到产品,则不应为聚合根创建存储库。为什么那个存储库在那里?如果它在那里,它不应该是产品可获得的唯一点吗? (所以也不要通过延迟加载!)。

这确实会产生很多开销和你可能不需要的代码(具有讽刺意味的是,YAGNI完全有效)。

好的,足够的咆哮。 DDD完全是关于思考。所以领域应该推动设计,通过实践,你将获得一个代表现实的领域模型。这并不是说你应该只是因为你在某个地方阅读而应该实现很多代码。相反,如果您已经识别了域元素,聚合根等,那么您必须在某处放置这些类型的行为,例如在域类中。您可以将获取逻辑放在单独的类中,例如订单存储库中的面向订单的提取逻辑,但它不是严格意义上的存储库(例如,它没有自己的本地缓存等)。这并不是那么糟糕,而是关于你应该为你的客户创造什么。

所以,首先:思考,第二:思考,第三:再思考......对你而言似乎合情合理。列出您拥有的选项的优缺点,并选择最适合您的选项。记录那个选择以及为什么选择那个而不是替代品。这给维护者带来了比任何其他来源更多的价值:你记录了替代品以及为什么你没有选择它们,你研究什么对你有用,你选择了一个。

软件工程并不难,只是现在看起来时尚只是先做,然后再思考,没有正确的推理 为什么 一个人会这样做,不是另一种方式。

祝你好运:)

答案 1 :(得分:1)

要考虑的其他因素包括产品的可能寿命以及在生命周期中任何时候必须从LINQ-to-SQL转换为其他O / R映射器的可能性。项目越小,产品越不重要,就越需要担心将minutae抽象到n度。