服务应该依赖于许多存储库,还是打破它们?

时间:2010-02-12 03:40:56

标签: design-patterns service repository-pattern

我正在使用存储库模式进行数据访问。所以我基本上每个表/类都有一个存储库。我的UI当前使用服务类来实际完成任务,并且这些服务类包装,因此依赖于存储库。在许多情况下,我的服务只依赖于一个或两个存储库,因此事情并不太疯狂。不幸的是,UI中的一个表单要求用户输入跨越五个不同表的数据。对于这个表单,我创建了一个依赖于五个存储库的服务类。然后,服务中用于保存和加载数据的方法在所有相应的存储库上调用适当的方法。

可以想象,此服务中的保存和加载方法非常大。此外,单元测试此服务变得非常困难,因为我必须设置这么多假的存储库。

将这项服务分成几个较小的服务是否是一个更好的选择?它会在UI层添加更多代码,但会使服务变得更小,更易于测试。

4 个答案:

答案 0 :(得分:1)

我没有每个表/类的存储库类。

每个'模块'或'root-aggregate'应该有一个存储库。这就是某个存储库可以覆盖的不仅仅是一个表。我们已将相关表分组到一个存储库中。例如,我们在表,Orders,OrderLines,FlightRepository等表顶部的不同表(如Person,Company和OrderRepository)之上有一个RelationRepository,用于存储Flight的所有数据等。 这是repositorypattern,因为您应该根据域驱动设计使用它。

答案 1 :(得分:0)

一种可能性就是按照您的建议拆分服务,但是创建一个用于处理这些存储库并保持单一服务的外观也是合理的。这将允许您在服务和数据操作中分离业务逻辑,并且可以在存储库之间和之间流动。

答案 2 :(得分:0)

我想说,如果你可以将保存抽象到每个存储库,而不是从服务中调用抽象,那么你就可以更加可测试和维护代码,而不需要在你的UI中添加任何额外的代码。

我目前有一个UI,它调用多个服务来将输入保存为单一形式(异步),让它正常工作是一件痛苦的事。您遇到的最大问题是处理验证和错误。第一位可能是正确的,但第二位失败。您必须返回并删除第一位,因为它已经保存。相信我,这是一种痛苦。

答案 3 :(得分:0)

我想我会专注于中段的两句话:

首先,为什么服务类中的保存和加载方法“真的很大”?你可以分手吗?也许那里有较小的单元可以单独测试。或许,这可能会指向将服务分解为您的服务委托其大部分工作的许多子组件。您可能希望避免将更多代码添加到沿着该路径的UI层,因为UI仍然只能与一个服务进行交互,但您可以单独测试所有组件。

其次,为什么在测试工具中设置假存储库如此困难?你能让那更容易吗?我经常使用构建器来设置类似但不相同的数据结构以供测试使用。然后你最终得到的测试是“给定通常的设置,除了差异X ,检查Y是否发生”。

另一个想法是注意到数据访问代码通常非常重复,并且经常可以根据您的数据库模式自动生成大部分代码。我们生成了大部分基本数据访问层,包括用于测试的虚假存储库类实现。当然,我们必须对性能关键位进行手工编码,但它需要花费大量的苦差事,并且可以轻松处理模式的更改。