抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

不要让“Clean Code”更难维护,请使用“Rule of Three”

2020 年 4 月 20 日

不要让“Clean Code”更难维护,请使用“Rule of Three”

“我们如何证明,通过遵循“代码整洁之道”(Clean Code)就可以编写更多的代码呢?”


当人们试图将“代码整洁之道(Clean Code)”的原则应用于现有的代码库时,我经常会问这个问题。


我认为这是合情合理的。


当我们开始重构遗留代码时,通常会将内容提取到较小的方法中。然后再将方法提取到类中。很快,我们可能就能感觉到原来 30 行的方法现在已经分散在不同的类中。


我们想知道的是:这在实际上是否是更容易维护了呢。


也许我们是一个小团队。也许我们必须支持我们继承的一个相对较大(并且没有文档记录的)的代码库。


寻求代码可维护性是一件好事。


错误在于,认为代码可维护性与代码行数(lines of code,LOC)相关。LOC 可能是一个有趣的度量指标,但它并不是关键所在!


不要使用 LOC 作为代码可维护性的度量指标。


简短的代码并没有更好的可读性。

如果你对此有所怀疑,那么应该看看“短码之美(Code Golf)”。


当我们进行“短码竞赛”时,我们的目标是找到一些聪明的技巧,用最少的代码字符来实现相同的功能:


// 31 个字符  Math.floor(Math.random() * 100)
// 21 个字符 ~~(Math.random()*100)
// 19 个字符 Math.random()*100|0
复制代码


但当然,这只是一个“strawman”的论点!


我相信我们不会以“短码竞赛”的方式来编写生产中的代码。


然而,有一个重要的原则,我们需要记住:


代码不是我们告诉计算机怎么做的方式;而是告诉另一个程序员我们想要计算机做什么的方式。


简而言之:编写代码是要供他人阅读的


易于理解的代码才是易于维护的代码。


还是,难道我们还不够聪明,而无法阅读冗长的函数吗?出于可读性的考虑,添加一堆一次性使用的助手函数又有什么好处呢?


如果这些问题能引起我们的共鸣,那么我们需要知道一个秘密……


过早的重构是项目失败的根源

任何极端的做法都是有害的。


即使是遵循“代码整洁之道”的原则。


我们正在尝试一些事情。当然,我们可以按照最佳实践来重构代码,但这同时也会增加了维护的难度。如果我们为了达到此目的而只是封装了一个条件语句,那么它可能没有帮助!


不,我们不应该为了可读性,而将所有内容都提取到“一次性助手函数”中。如果我们每次阅读代码时都需要阅读这些函数的主体,那么这一点也没有帮助。它只会是阻碍。


我们应该做的是,创建正确的抽象。


正确的抽象,正确地划分职责。它们阐明了代码的意图。它们可以防止代码重复。


当我们找到正确的抽象时,我们会觉得这 4 个类实际上比原来的 30 行代码更易于维护。


但是,要找到正确的抽象确实很困难。因此,这就是我们应该关注的重点。


坏的抽象比重复更糟糕

你是否听说过“不要重复你自己(Don’t Repeat Yourself,DRY)”原则?


这是一颗共同发展智慧的明珠,而且非常有效。但它也经常被误解。


两段代码看起来是一样的,但却代表了不同的概念。不同的抽象。在这种情况下,重复是偶然的。保留重复会更好。


“重复与错误的抽象相比,代价要小的多”

—— Sandi Metz, 所有的小事


什么时候应该将代码提取到函数/方法/类中?什么时候应该保留重复?我们怎么知道我们有正确的抽象呢?


使用“Rule of Three”

Also called Write Everything Twice (WET). Pun intended.


这也称为“什么都写两遍(Everything Twice,WET)”。这是个双关语(与 DRY 原则相对)。


“三次重复攻击,就重构”


重构原则“Rule of Three”是一条经验规则,当我们有疑问时可以使用它。


在引入抽象之前,请等待第三次重复的出现。出现重复的次数越多,就越容易找到要提取的共性。


遵循“Rule of Three”原则。它能使我们更容易地找到正确的抽象。


超越“Rule of Three”

这里的“Rule of Three”原则是为了提醒我们,重复是可以的。


这也有点教条。就像“代码整洁之道”的原则一样,不要在任何时候都盲目地 100%应用它。


有时,即使出现了 3 次重复,我们也可能找不到正确的抽象。不要强求对代码库进行过度的抽象。如果我们不能给它起一个清晰的名字,它就确实不够清晰。


毫无疑问,违反规则是可以的。等待更多的重复。


宁可重复,也不要错误的抽象。不要为了抽象而创建抽象。


如果抽象不好,则必须使用布尔型的参数和 if 语句来简化它的实现,以覆盖新的用例。这只是一种暗示、一种警告,告诉你你走错了方向。


如果我们还没有找到抽象的话,那也没关系。当我们有了更多的上下文时,仍可以重构它。等着瞧吧!


原文链接:


https://understandlegacycode.com/blog/refactoring-rule-of-three/


2020 年 4 月 20 日 09:001608

评论 1 条评论

发布
用户头像
这篇文章总结一句话就是:事不过三,三则重构
2020 年 04 月 20 日 12:25
回复
没有更多了
发现更多内容

关于Vue权限路由思考

HaiJun

Vue 前端 vue-router 权限认证 按钮权限

局域网服务器访问外网方案

lockdown56

Linux 网络 路由表

记上周双休日的加班

sadhu

加班

零信任提升组织的数字安全性

龙归科技

网络 数字时代 零信任

“数字足迹”怕暴露,数字人民币如何守护你我隐私安全?

CECBC区块链专委会

数字货币

从新手到专家:如何设计一套亿级消息量的分布式IM系统

JackJiang

架构设计 即时通讯 IM

推动产业数字化 提升服务实体经济质效

CECBC区块链专委会

科技

OKR实践中的痛点(4):再谈老板的KR我的O

大叔杨

OKR 敏捷 绩效 敏捷绩效

缓存不一致、缓存雪崩、缓存击穿、缓存穿透

escray

redis 极客时间 学习笔记 3月日更 Redis 核心技术与实战

满满干货|支付宝美女面试官的贴心锦囊

Lily

Java反射简析

Langer

Java java反射

记一次生产环境大面积404问题!

冰河

nginx 网关

Java + opencv 实现图片人脸检测

张音乐

Java AI OpenCV ffmpeg 人脸识别

Redis - 主从模式

insight

redis 3月日更

聊聊集群、分布式和微服务之间的异同点

架构精进之路

分布式 微服务 集群 3月日更

工作三年,小胖不知道 MySQL 日志是干嘛的。真的菜

JavaFish

MySQL mysql事务 MySQL日志

高性能公链能为 DeFi 带来什么?

CECBC区块链专委会

区块链

双非怎么了

我是程序员小贱

3月日更

如何快速掌握 Kubernetes 网络

倪朋飞

学习方法 Kubernetes 云原生

跨越数据的“叹息墙”:华为下一代数据湖与HPDA时代

脑极体

如何激励员工?—— 马斯洛需求理论

石云升

激励 28天写作 职场经验 管理经验 3月日更

Centos7下Docker安装&配置&镜像加速

happlyfox

学习 ,docker 3月日更

go + ffmpeg + goav 实现拉流解码器

张音乐

go 音视频 ffmpeg goav

【Axure9百例】47.CSDN的列表样式

zhuchuanming

原型设计 Axure 交互原型

算法:求两个单向链表的最早公共交点

程序员架构进阶

算法 链表 28天写作 3月日更 算法解析

FFmpeg应用篇

Changing Lin

3月日更

PS 进行隐藏图制作

空城机

PhotoShop ps 视觉处理 视觉 隐藏图

工作四年,分享50个让你代码更好的小建议

比伯

Java 程序员 架构 程序人生 计算机

普元CTO焦烈焱:成长之路务必重视工程能力

EAWorld

程序员

《MySQL》系列 - select 查询语句到底是怎么执行的?

JavaFish

MySQL 数据库 原理 sql查询

Java + opencv实现视频人脸检测

张音乐

OpenCV 人脸识别 视频

Study Go: From Zero to Hero

Study Go: From Zero to Hero

不要让“Clean Code”更难维护,请使用“Rule of Three”-InfoQ