被误解的单一职责原则 - Joe


谷歌工程主管乔·林奇的文章,获得SOLID原则作者鲍勃大叔点赞转发的文章:
作者推荐将SRP视为DDD原则的自然结果:跨DDD限制上下文共享的模型是不安全的。
单一职责原则 (SRP) 是SOLID设计原则中的第一个,自 2000 年由罗伯特·马丁(“鲍勃大叔”)引入以来,它们在软件工程中产生了极大的影响。不幸的是,这一特定原则经常被误解。再加上盲目的信念,这可能会导致过于简单化的思维和设计错误。
该原则经常被定义为“每个软件模块都应该有一个且只有一个改变的理由”。然后这个名字似乎暗示该模块应该有一个“单一的责任”。这似乎很容易理解。所以模块应该只做一件事,对吧?  
不对!
有一个另外不同的经验法则:一个函数才应该只做一件事:您是否曾经在命名诸如“ImportData And LoadIntoDatabase”之类的函数时捂住鼻子。我们知道这一点:一个函数应该有一个单个功能。
 
SRP单一职责是保证凝聚力(banq:包含的职责功能越多,凝聚力越弱;单一的职责能提高凝聚力 =>高凝聚低耦合)
该原则实际上意味着给定模块中的代码必须由一个且只有一个最终业务所有者(或功能单元)拥有。如果这不是真的,你必须打破它。
Bob 大叔举了一个例子(书面谈话),其中 CFO 和 COO 都依赖于计算员工工时的代码:其中一位高管要求更改该代码,但这违反了另一位高管所在部门的业务规则,因此工时计算是不能共享的,这样这段代码应该有一个CFO财务版本和一个COO运营版本,尽管这违反了我们的DRY 和凝聚力的敏感性。
这与我看到的大多数人应用 SRP 的方式非常不同。
虽然我不需要每天都应用它,但 SRP 确实符合我的经验:
我在运输管理系统上工作,我们有一个代表卡车运动的对象。它本质上是可操作的——您可以指定司机、送货地点的到达和离开时间等。该对象的另一个版本用于支付司机的费用。这些对象是一对一的,有很多明显的重复。它真的把我逼疯了!有几次我试图用相同的代码统一对待它们,但它不可避免地失败了。你猜怎么着?一个对象属于运营,一个属于(你猜对了)财务。  这正是鲍勃叔叔所说的。  虽然 SRP 是正确的,但有时很难主动应用,因为谁(或哪个组)是某事的“最终所有者”可能很模糊并且需要时间才能变得清晰,尤其是如果您正在与许多利益相关者一起从头开始构建系统。
从另一个角度来看,我将 SRP 视为DDD原则的自然结果:拥有跨有界上下文共享的模型是不安全的。
 
世面上错误解释单一职责SRP
不幸的是,我看到很多人盲目地遵循对 SRP 的错误理解。通常喜欢小型“类”的人会用它来证明制作更多甚至更小类的理由。
一开始是一个简单、易于理解的类,最终被分解成许多现在从集合集体级别上很难理解的抽象(banq注:太琐碎,一地鸡毛,代码小类的数量太多了)。
无论您是否喜欢这种风格,SRP 本身都不会是这个意思。
我最近阅读了自适应代码(第 2 版,Microsoft Press),截至今天,在亚马逊上的评分为 4.7/5,评分为 123:SRP 有一整章。在整个过程中,它错误地将 SRP 解释为与做太多事情的类有关,并仅以此证明设计决策的合理性。
出于凝聚力的原因,类确实不应该做太多事情;所以设计决策并不总是糟糕的。
但是,作为一个例子,一个有 2 页代码的类被分解为大约 12 个类和接口(类的数量太多),所有这些都以被误解的 SRP 的名义。
这是一本由一位有成就的作者所著的受人尊敬的书,而不是一些随意的博客文章。
 
SRP起源
我们必须鼓励新的工程师理解这些原则背后的推理,与它们搏斗,在它们有意义时应用它们,在它们没有意义时拒绝它们。
研究回到源头也是很有启发和吸引力的。
SOLID原则植根于早于我们这一代的核心设计原则:比如介绍信息隐藏概念的Parnas论文和Constantine介绍耦合和内聚概念的那本书。
鲍勃大叔认为这些作品影响了他的思维。 在他的演讲中,通常在他必要的、随机的物理学漫谈之后,他总是努力将现在和过去联系起来。 这是一个伟大的事情。
但是,我们周围并没有很多鲍勃大叔。 作为一个行业,我们并没有很好地将经验代代相传。 我们能做些什么呢?
虽然说 "太阳底下没有新鲜事 "是一种夸张的说法,但令人惊讶的是,我们经常与老问题搏斗,却没有意识到我们可以站在前人的肩膀上。
 
从无界从有界
为什么我们作为工程师会喜欢这些设计原则呢?(我知道我喜欢。)除了它们的启发式效用之外,我认为这是因为它们为本来是无边界的解决方案空间提供了感觉上的约束。
它们减少了焦虑,并在无法确定的地方引入了一些可以确定的东西。
通常情况下,我们是一个叛逆的群体,讨厌约束(告诉别人他们必须使用vim或emacs)。 但是,当我们面对一个开放性问题的深渊时,约束是我们的朋友(banq注:当你凝视深渊时,深渊也在凝视你,你不至于成为深渊的原因是你能约束自己)
基于经验的观察变成了原则,变成了经验法则,变成了正式的规则,最后僵化成法律。(banq注:道可道非常道,名可名非常名,读书的人基本是教条主义与自以为是者)
因此,在这里我们要小心!
撇开物理学不谈,我在软件工程中发现的唯一绝对规律是没有规律可寻!(banq注:一切可变,唯一不变的是变化) 毕竟,我们是在用比特字节建造城堡。