0

在找到这篇文章之前,我不知道角色特定的存储库:

我们可以选择将接口隔离原则应用于基于角色的接口,并定义只公开一个类需要的接口,而不是一个公开所有方法的包罗万象的存储库。

public interface IProductRepositoryForNewOrder
{
    Product[] FindDiscontinuedProducts();
}

单个存储库实现实现了所有产品存储库接口,但调用者只公开和使用所需的单个方法。

a) 两者之间的区别在于,对于特定存储库,我们每个聚合根有一个特定的合约,而角色特定的存储库我们可以每个聚合根有多个合约,这些合约中的每一个都是针对在聚合上运行的特定调用者的需求量身定制的根?

b) 在您看来,这两种模式各自的优缺点是什么?

谢谢

更新:

昨天我找到了您的一个答案,本质上您认为应该使用角色特定的存储库模式:

“另一种选择是使用 lambda 代替 OrdersSelectorService。如果 lambda 在您的语言中不可用,那么它应该是一个接口。传递 OrderRepository 的好处是基于接口隔离原则,其目标是减少不必要的耦合。 Customer 的行为不太可能需要 OrderRepository 上的所有方法,而是需要一个特定的函数,所以要明确说明。”

为什么在上面的摘录中您提倡使用角色特定存储库模式,但在这里您似乎建议仅在特殊情况下使用它。另一个主题中的示例是否是特殊情况(除此之外 - 我绝不是说您在自相矛盾,我只是看不出这两个示例在使用或不使用角色特定模式方面有何不同) ?

4

2 回答 2

2

a) 是的。这就是接口隔离原则。明确角色/用例。好处是减少和“清理”依赖关系。

b) 对我来说,角色特定方法的主要缺点是接口的激增以及由此导致的布线、引用等的增加。然而,这种缺点可以被视为不是由于原理上的缺陷,而是更多在编程语言中。在诸如 F# 之类的函数式语言中,由于函数而非接口的激增,接口隔离是默认方法。从某种意义上说,函数是一种“更锋利”的工具。

非角色特定方法的优点在于它可以被视为定义数据访问契约的单一语言元素、接口或类。在某些情况下,从技术角度评估架构是很有价值的。

于 2013-01-09T06:29:34.767 回答
2

我完全支持 SOLID 代码,但接口隔离原则确实有其局限性,尤其是在 DDD 上下文中。

[挑剔模式]

如果您将 ISP 应用于这封信,您几乎可以从文章中获取关于存储库的声明并稍作修改以说明

使用域实体的类​​很少使用其中的每个方法。

因此,对于每个领域实体,您应该创建与实体的客户端一样多的接口,每个接口中只包含与客户端相关的方法,并让实体实现这些接口。

当然,这是荒谬的,没有人会这样做。但是,嘿,ISP 应该是一个通用的 OO 概念,不是吗?

[/ nitpicker 模式]

现在,如果我们回顾一下 ISP 存在的最初原因,它应该与胖接口(即没有内聚性的接口)作斗争。但是存储库本身不是有凝聚力的吗?它不是一个基本的、原子的 DDD 构建块吗?它是否值得分成几十个迷你查询对象?此外,我们领域中的每个类不应该与通用语言对齐吗?对于诸如ProductRepoInterfaceForClient1, ProductRepoInterfaceForClient2, ProductRepoInterfaceForClient3...之类的接口,情况并非如此。

不要误会我的意思,ISP 仍然很有用,尤其是作为一种检测接口的合同何时比应有的更加异构的方法。Bob 大叔关于 ISP 的原始论文有很好的例子——参见“接口污染”段落和 ATM 示例。

但是一旦达到了合理的内聚水平,ISP 不应该盲目地应用 IMO,特别是如果它与基本的 DDD 原则相冲突,或者用数百个接口淹没你的代码库,这成为维护的噩梦。

于 2013-01-09T13:17:28.543 回答