问题 “高凝聚力”是“单一责任原则”的同义词吗?


高凝聚力 同义词 单一责任原则? 如果没有,它们有何不同?


8342
2018-06-26 20:05


起源



答案:


这不是一回事。

你可以拥有一个高度凝聚力的课程,而不仅仅是一个人。


6
2018-06-26 20:09



相反的情况可能是正确的:一个实现单一责任的阶级可以与许多事物相结合。 - bluevector
@jonnyGold - 高凝聚力(在一个类中)和耦合也是不同的东西...... - Oded
确实。然而,它们(耦合和凝聚力)通常被视为对立,对吧? - bluevector
@ user1483278 - 是的。它归结为人们所说的责任。例如,数据访问类可以具有高度凝聚力,但如果它同时处理查询和命令,则使用CQRS的人会将其视为违反SRP。 - Oded
@ user1483278 - 在那个具体的例子中。虽然如果该类正在执行除数据访问之外的任何操作,但它仍可能违反SRP。 - Oded


答案:


这不是一回事。

你可以拥有一个高度凝聚力的课程,而不仅仅是一个人。


6
2018-06-26 20:09



相反的情况可能是正确的:一个实现单一责任的阶级可以与许多事物相结合。 - bluevector
@jonnyGold - 高凝聚力(在一个类中)和耦合也是不同的东西...... - Oded
确实。然而,它们(耦合和凝聚力)通常被视为对立,对吧? - bluevector
@ user1483278 - 是的。它归结为人们所说的责任。例如,数据访问类可以具有高度凝聚力,但如果它同时处理查询和命令,则使用CQRS的人会将其视为违反SRP。 - Oded
@ user1483278 - 在那个具体的例子中。虽然如果该类正在执行除数据访问之外的任何操作,但它仍可能违反SRP。 - Oded


你问: 如果没有,它们有何不同?

单一责任原则

抛出你认为这个原则意味着什么。

Robert C. Martin正式将此原则定义为:

一个班级应该有一个改变的理由

定义SRP的大多数人都是不正确的。 SRP通常被误解为:

“该 Employee 上课不应该 UpdateDemographics() 和 SendMessage(),这就算是两个责任......放 SendMessage() 进入Message类!!“

^^错了

vv对

罗伯特C.马丁说

“责任不是代码所做的事情”。 (NDC 2012)

Robert C. Martin将SRP定义为:

“任何模块都应该只负责 一个人 - [角色]。“(NDC 2012)

当一个 利益相关者 要求更改View中的数据排序,管理层不应该惊慌失措并担心算法会中断。因为 处理View上的排序的模块仅对利益相关者负责,和 处理总计算算法的模块仅对业务分析员负责。  因此,当业务分析师要求对算法进行更改时,我们不应该担心View会发生变化。

因此, 一个模块 (单数)应该只因为一个原因改变:单身人士 - 角色 该模块所服务的人请求更改。

有了它作为SRP定义的新基础,您现在可以应用您的 思想 之前的SRP,使定义更加细化。没有人会说将所有前端代码放入一个模块,将所有后端代码放入一个模块中。

高凝聚力

想象一下,你有一个方法 decimal CalculatePayFor(Employee) 和另一种方法 void Pay(Employee)

这些属于一起吗?可能有一个服务可以执行所有类型的计算,并且可能有一个服务只能包装人力资源支付SOAP。也许 Pay(Employee) 打电话给 CalculatePayFor(Employee),但仅仅因为他们有这个词 Pay 在他们中并不意味着他们属于一起!

我如何创造凝聚力?  - 你没有。凝聚力是你观察到的。你做的是 不要撕毁属于一起的东西。

可以为所需的每个公共方法创建一个类。每个类现在都有一个公共方法,一切都是明确的混乱。你有名字的班级 PayrollClass1 和 PayrollClass2 因为一个人以一种方式进行计算,另一个人以两种方式进行计算。

有些语言甚至可以从完全缺少类中获益,并且方法可以自由运行。没有方法分组,方法只是您可以随时调用的方法。它们几乎都是静态的。

然而, 你可以观察 那 CalculatePayFor(Employee) 和 Pay(Employee) 实际上非常非常 。他们就像一对夫妻,他们看起来很棒。当方法明显属于一起时,你不想将它们分开。观察它们的自然状态并建立一个野生动物保护区。这是 保持高凝聚力。你没有创造它,你观察它。

这真正有用的是 正确的代码重复。例如, PayrollService.CalculatePayFor(Employee) 具有与之相同的确切代码 ReportService.CalculatePayFor(Employee)。这不好吗?当然不是。如果高级管理层要求为报告而改变员工薪酬的计算,那么与H.R.告诉您对实际支付方法的税收计算进行更改的责任不同。

“等等,他只是混淆了SRP和Cohesion吗?”不,但我很高兴你认识到混乱。如果ReportService进入Pay​​rollService类并使用其方法怎么办?然后,当它为合法付款目的而改变时,报告全部改变......但管理层不希望这样!因此,由于Cohesion强制方法保留在自己的类中,并且SRP强制模块在应用程序中保持自身,因此ReportService被强制从PayrollService类复制/粘贴方法。现在他们可以彼此独立地改变。

“但如果这不是你想要的呢?”嗯,代码中有很多地方可以排除重复。但算法最常见的是坚持自己,并且独立于依赖性而改变。即使这意味着重复。这取决于需要什么。但是,关注点分离,单一责任,凝聚力和干燥(不要重复自己)都是独立的想法。

侧注:DRY并不意味着永远不会重复。正如我所提到的:很多时候你可以拥有重复的代码,因为业务规则在不同的关注点之间是相似的,并且有不同的改变原因。


7
2018-01-12 23:11





它不是同义词。 SRP(单一责任原则)是指您确保您的课程只承担一项责任。这肯定会增加你的课堂凝聚力。

但是你可以在不遵循SRP的情况下获得高凝聚力。

这里 是一个很好的来源。


3
2018-06-26 20:41