在他的帖子SOLID: the next step is Functional中,Mark Seemann说:
如果您继续将设计推向越来越小的界面,您最终会到达最终的角色界面:使用单一方法的界面[...]如果您应用SRP和ISP,那么您和#39;可能会使用许多细粒度类来演化代码库,每个类都有一个方法。这不止一次发生在我身上。
我关注的是这些课程的凝聚力。这种方法是否适用于此 功能凝聚力?这些课程是否不相干? 是否会对代码一致性产生不良影响?
答案 0 :(得分:2)
书中Growing object oriented software guided by tests提出了一个关于凝聚力的伟大定义,其中陈述如下:
元素的凝聚力是衡量其责任的标准 形成一个有意义的单位例如,一个解析两个日期的类 和URL不一致,因为它们是不相关的概念。考虑到 洗衣服和洗碗的机器 - 两者都不太可能 好。在另一个极端,一个只解析标点符号的类 在URL中不太可能是连贯的,因为它不代表一个 整个概念。为了完成任何事情,程序员必须找到 协议,主机,资源等的其他解析器。功能与 “高”连贯性更容易维持。
这可能会很快进入主观领域,但我认为SRP和凝聚力有时是直接相关的和正交的概念。如果你的课程只有一种方法,那么肯定的是,它只是在一件事情上才具有凝聚力。但是,你也失去了一些东西,即。这个班级现在太精细了,不能自己使用。
在功能风格中,拥有这样的课程很有意义。它是关于组合函数以实现结果的全部内容。 C#使这种风格成为可能,但也非常冗长,所以我完全赞同Seemann在他以这种方式设计你的代码库的情况下争论F#时。
问题是这个好的或坏的设计是主观的,但我认为我们可以客观地说几件事。一个方法类本质上几乎可以保证尊重SRP(当然,你仍然可以忽略这一点并用一种强大的方法制造上帝类)。因此,以这种方式编写的代码应该具有我们期望的所有好处,即。松散耦合,可组合和可维护。但也有一些关于失去这些代码的大局的话。
我认为在大多数情况下需要两者的某种组合,在大多数代码库中都倾向于使用单一方法的类。例如,您可以编写大多数低级代码,例如可重用的库集合,具有此类。一旦接近API级别,就可以组合这些类来获得所需的逻辑,然后将这些逻辑公开给客户,作为更具凝聚力的功能块。客户端可以获得更加紧密的高级代码路径,从而更方便地使用,并且可以更好地发现您的库支持的功能,同时还具有以下方式编写低级代码的所有好处。变得可维护和灵活。