2

在他的帖子SOLID: 下一步是功能性的,Mark Seemann 说:

如果您不断推动您的设计朝着越来越小的接口方向发展,您最终会到达最终的角色接口:具有单一方法的接口 [...] 如果您像这样应用 SRP 和 ISP,您可能会进化具有许多细粒度类的代码库,每个类都有一个方法。这在我身上发生了不止一次。

我关心的是此类课程的凝聚力。这种方法是否会促进功能凝聚力?这些类没有凝聚力吗?对代码一致性有不良影响吗?

4

1 回答 1

3

在《以测试为指导的面向对象的软件成长》一书中对凝聚力有一个很好的定义,其中陈述如下:

一个元素的凝聚力是衡量其职责是否形成一个有意义的单元的指标。例如,解析日期和 URL 的类是不连贯的,因为它们是不相关的概念。想想一台既能洗衣服又能洗盘子的机器——它不可能两者都做得很好。在另一个极端,只解析 URL 中的标点符号的类不太可能是连贯的,因为它不代表一个完整的概念。为了完成任何事情,程序员必须为协议、主机、资源等寻找其他解析器。具有“高”一致性的特征更容易维护。

这可能很快就进入了主观领域,但我认为 SRP 和凝聚力有时是直接相关且正交的概念。如果你的类只有一种方法,那么可以肯定的是,它在某种意义上是具有凝聚力的,它只做一件事。但是,你也会失去一些东西,即。该类现在粒度太细,无法单独使用。

在函数式风格中,拥有这样的类很有意义。这都是关于组合函数以实现结果。C# 使这种风格成为可能,但也非常冗长,所以我完全同意 Seemann 的观点,他支持 F#,因为无论如何你都在以这种方式设计代码库。

这个设计是好是坏的问题是一个主观的问题,但我认为我们可以客观地说几件事。一个方法类本质上几乎可以保证尊重 SRP(当然,您仍然可能会错过重点并使用全能方法制作神级类)。所以以这种方式编写的代码应该具有我们所期望的所有好处,即。松耦合、可组合和可维护。但是也有一些关于丢失此类代码的大图的说法。

我认为在大多数情况下需要将两者结合起来,在大多数代码库中倾向于使用单一方法的类。例如,您可以编写大部分低级代码,例如可重用的库集合,具有这样的类。一旦您接近 API 级别,您将组合此类类以获得您想要的逻辑,然后将此类逻辑作为更具凝聚力的功能块公开给您的客户。客户将受益于拥有更具凝聚力的高级代码路径,从而更方便地使用和更好地发现您的库支持的功能,同时还拥有以这种方式编写低级代码的所有好处可维护且可灵活更改。

于 2016-09-05T07:39:34.653 回答