【问题标题】:Is a class with only one function cohesive enough?只有一个功能的类是否足够有凝聚力?
【发布时间】:2016-09-04 20:29:55
【问题描述】:

Mark Seemann 在他的帖子SOLID: the next step is Functional 中表示:

如果您不断将设计推向越来越小的接口,您最终会得到最终的角色接口:具有单一方法的接口 [...] 如果您像这样应用 SRP 和 ISP,您将可能会演变出一个包含许多细粒度类的代码库,每个类都有一个方法。我不止一次遇到这种情况。

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

【问题讨论】:

  • 缺乏凝聚力意味着“做太多事情”、“有太多责任”。只有一种方法与更少的责任相关——只要你不把那种方法变成超级无所不能的方法。

标签: class-design solid-principles single-responsibility-principle decoupling cohesion


【解决方案1】:

Growing object oriented software guided by tests 一书中对凝聚力有一个很好的定义,其中陈述如下:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多