我还记得我第一次提出拉票要求时, 文件有800行长,一个函数试图验证输入,从三个不同的API取取出数据,转换结果,更新UI,将所有数据都登录到一个无人看过的控制台上.
我花了三个小时用一个调试器穿过它, 只是为了意识到这个虫子是一个可变名称的打字器, 埋入了三个层次深处的巢中。
当我终于修好它时,我觉得我刚刚打败了一只龙...只是为了发现龙藏在它的洞穴里有十几只更小的龙.
经历让我好奇: 为什么代码很难读,即使它有效?
答案不是一个奇特的框架或新的语言特征, 一旦我开始把规则当成神圣的誓言, 龙开始收缩, 我的代码开始感觉像一个干净的,良好的走廊 而不是一个黑暗的,缠绕的森林。
启示录( 透视) 这项原则是直截了当的,但其影响是巨大的:每一项职能都应承担单一的责任。
如果您能描述一个函数对单个动词短语- validate UserInput, 获取 UserProfile, 渲染出 Dashboard- 您在正确的轨道上。
如果你需要一个“和”或“但是”的描述,你可能已经得到了不止一份工作。
这有什么关系?
可读性:读者可以用秒来掌握意向,而不是分钟.
可检验性:小而有重点的功能对于单位测试来说是微不足道的.
你可以嘲笑依赖性 并断言结果 不设置一个整体的saga。
调试:当出错时,堆栈会直接指向负罪性功能,而不是20‐线单体,你必须猎取违法行.
可重复性(Reusubility):一个能很好地做一件事的函数,可以在最小摩擦的情况下被降入代码库(甚至其他工程)的其他部分.
把它当成一个组织良好的工具箱 如果每个抽屉只拿着螺丝刀, 你从不浪费时间寻找扳手 当你需要收紧螺栓。
密码也一样 连接电源( 代码和示例) 让我们看看现实世界违反规则的片段, 前 – “ 做一切” 函数 这里发生了什么?
校验,数据访问,密码检查,令牌创建,和响应格式化都是被纠缠在一起的.
如果我们需要改变我们的散装密码, 我们必须潜入这个怪物 并冒险打破其他的东西。
如果我们想在别处重用验证逻辑, 之后 – 单一责任函数 什么变了?
每个功能现在都做一件事,而且做得很好。
他们很容易孤立地进行单位测试, 管弦乐团()读作"高级":验证,取出,验证,表示,回应.
如果我们需要交换bcrypt的Argon2,我们只碰。
在另一个终点重用验证?
只是导入。
重新构思的版本在行数上更长,但这是件好事,每一行现在都带有明确的单一意图。
认知负载大幅下降.
为何采用“每个职能一个责任”规则, 我开始将每个功能看成一个自成一体的小故事。
当我打开一个文件时,我可以省略函数名称,并立即理解流量,比如在跳入一章之前读取目录.
虫子变得更容易被发现,因为有罪的一方通常是单一的,命名不好的功能,而不是一团乱.
与我合作的团队也注意到了差异。
拉动请求评论从“这到底做什么?” 转到“这个函数名称是否与其行为相匹配?” 和“我们能将这个重复的块提取到自己的帮助者吗? ” 代码库感觉更可维护,登上新开发者需要一半t