细节中有上帝,论精简代码
本文最初发布于 Medium 网站,经原作者授权由 InfoQ 中文站翻译并分享。
在我开始担任软件工程师的那一年(2007),Bob 叔叔出版了他的第一本书《代码整洁之道》的首版。那时,我在一家制造业公司工作。由于那是一家制造公司,所以工作中会接触很多精益实践和方法论,于是我决定深入学习了解一下相关知识,并获得了六西格玛绿带认证。
大约在我获得认证的那年,我也读到了这本书,但那时候它并没有给我带来任何启迪。等到我第四遍读这本书时,我正在为一些接受我培训的开发人员准备一组关于整洁代码的培训课。就在那时,精益与整洁代码两种方法论的一点一滴开始在我的脑中交织融合在一起,我开始领悟了。
首先定义“精益”。从最纯粹的意义上讲,它是一种旨在 组织 人类活动,以在消除浪费的同时提供更多价值的方法。
人们采用了许多不同的方式来定义精益方法论,只不过他们选择的名称可能不太一样。所有这些 规范 都多少会关注精益原则。
为了 组织 和 纪律,你首先必须 看到 要组织和遵循纪律的事物。而且由于我们谈论的是代码,所以当你看到它时,实际上是在 阅读 它。稍后我们继续这个话题。
现在我们来定义“整洁”。回想一下你的童年,妈妈曾经(或仍然如此)说:“你必须打扫完房间才能出去(是的,当年我们真的是出去玩,而如今你是要上网娱乐)和朋友一起玩”。
当你开始打扫房间时,你会意识到要提高效率,第一步是先把所有乱糟糟的东西分门别类(Sort),把电子游戏放在这一边,杂志归拢到另一处,玩具收纳在那里,等等。然后为每组分好类的东西分配一个位置(Set in order)。现在你就可以更轻松地做清理工作了(Shine)。最后你意识到,为了让房间中的各种东西保持(Sustain)整洁,更简单的做法是先制定一套日常管理规则(Standardize),这样你就用不着打扫房间了,可以快点出去和小伙伴们玩耍。
这就是众所周知的 5 步方法论,它与我们的整洁(精益)代码模型完全一致。
5 步方法论是:
一种方法,可以让工作场所整洁有序,井井有条,以帮助减少浪费并提高生产率。
通过标识和存储所使用的物品,管理区域和物品并保持秩序来组织管理工作场所,以提高效率和有效性。
将它与整洁代码方法论结合起来是这样的:
说实话,每个人都可以成为一名程序员。如今有这么多现成的工具、友好的框架和编程语言,任何人都可以观看免费视频并学着编写一段计算机可以理解的代码。但真正困难的部分在于:将软件工程付诸实践并编写出人类也可以理解的代码。
继续说实话:如果你写的不是“整洁代码”(至少不是受人尊敬的代码),你就不能称自己为软件工程师。你能想象一位医生的办公室是乱糟糟无法驻足的场景吗?书躺在地上,桌子上有垃圾,衣服不整洁。你愿意和他一起做一次心脏手术吗?
现在,我们来谈一谈为什么整洁代码如此重要的原因所在:
代码更具可维护性。
建立可持续发展的业务
它使你看起来更专业。
易于阅读和理解。
提高生产率。
避免重新设计的恶性循环。
“上帝在细节中”,建筑师:路德维希·密斯·凡德罗
如前所述,精益是一种方法论,是一组旨在组织人类活动以在消除浪费的同时提供更多价值的规范。但是,你无法整理和约束看不见的东西,而要真正能"看到"代码,代码就必须是可读的。你无法改进看不见(无法阅读)的内容。所以我们先来讨论整洁(精益)代码原则的第一个支柱。
下面 可读性 的完美定义:
清晰。“如果想快速执行,如果想快速完成,如果想让代码易于编写,请让代码易于阅读”—— Robert C.Martin
简单。不要过度设计。
表达的密度。使用最少的资源和交互以获得最多结果的艺术。
有意义的名称:
可以揭示意图的名称(为什么存在,其用途以及使用方式)。
使用动词表示函数名称,使用名词表示类和属性。
变量应表达自身的创建目的。(避免使用 var x,而应使用 var customersIndex)
命名约定:
✓一定要选择易于理解的标识符名称。
✓一定要先考虑可读性再考虑简洁。
✓一定要使用语义上有意义的名称,而不要使用特定于编程语言的关键字来写类型名称。例如,GetLength 就比 GetInt 更好。
X 请不要将缩写用作标识符名称的一部分。比如应该使用 GetWindow 而不是 GetWin。
X 请不要使用与广泛使用的编程语言的关键字冲突的标识符。
X 请不要使用任何不被广泛接受的首字母缩写词,就算它们被广泛接纳,也只在必要时才使用它们。
小方法:
一个方法应该是一个只做一件事情的可测试单元。
保持在 10 到 15 行代码之内。
如果你的方法更大,那么它可能正在做很多不该它来负责的事情。
“尽早返回”。
接下来,我们继续讨论整洁(精益)代码原则的第二大支柱。
由于我们在谈论的是代码,因此我们将专注于开发人员的工作,而开发人员会经常使用类。架构师的工作位于更高的层次上,不涉及代码,而是处理项目或服务(也称为域,微服务等)等等。因此我们将专注谈类。
源文件就像报纸的标题,其名称应该简单明了,光看名称就知道是什么模块。源文件的顶部应该提供关于高级概念和算法的信息,往下走逐渐展开细节,最后则是底层函数和细节。
3C 原则:
耦合:软件模块之间的关联性。
内聚:模块内部元素结合在一起的紧密程度。
组合:类应该根据其组合而非继承来实现多态。例如,一辆车不是一个发动机,而是集成了一个发动机,所以发动机之类的组件通过外部 API 组合起来形成高级抽象。
最后,我们来谈整洁(精益)代码原则的第三大支柱。
能力 = 纪律 + 技能
拥有良好的态度胜过拥有多年经验。
良好的态度是有感染力的。它会激励整个团队。
“你的态度,而不是你的才能,将决定你的高度。”——Zig Ziglar
纪律是一套标准、规则、试探法、原则和实践等。下面我来定义一些保持你的代码整洁的最佳方法:
童子军规则。离开营地时先打扫干净。每次编写代码时,我们应该稍微清理一下旧代码,是否是别人编写的都没关系。整理一下就可以做出一点贡献。只是不要疯狂清洗一大堆东西,否则你可能会破坏某些内容。
一定要非常简洁。记住,不要过度设计;不要用牛刀杀鸡。
YAGNI(你并不需要它)。不要因为将来可能添加更多功能就写一个工厂设计模式。等到需要的时候再创建工厂,不要提前行事。
最小意外原则。为每件事物找到一个地方,然后将其放置在其他开发人员更容易找到的地方。尽量不要放在会让别人感到意外的去处。
“如果没有测试,那就默认它坏了”。编写大量测试,尤其是单元测试,否则你会后悔的。
类和函数应该尽量小一些,并遵守单一责任原则(SRP)。函数不应超过 4 行,而类不应超过 100 行代码。是的你没看错。它们也应该只做一件事。
函数应该没有副作用。副作用(例如修改输入参数)是有害的。确保你的代码中没有副作用。尽可能在函数合约中明确这一点(例如,传递原生类型或没有 setter 的对象)。
避免重复。抽象出常见的事物并将它们放在一个位置,从而避免重复的代码。
如何避免重复
以后再做等于永远不会做。你有长长的待办事项列表,但你内心深知你永远不会完成它们。一个好办法是,每次加入新的待办事项时都写一条自己正在处理的事项。
4 人代码审查规则。为了确保你完全遵循所有标准和最佳实践等,你应该总是要求 4 个人来审查代码:身边找两位开发人员,你的技术主管以及最重要的是 你自己。你审查自己代码的时候应该和审查别人代码时一样严谨。
代码分析工具。Resharper、IDE 企业版、SonarQube、SpotBugs 之类的工具可以帮助你遵守最常见和关键的代码准则。
不要学其他那些只看什么线上免费课程,并从某些公共仓库复制粘贴的程序员。要有专业工程师的样子,让自己编写最好的代码,写出可读、有条理且遵循所有规范(内部和外部规范)的代码。
感谢阅读。感兴趣的话可以关注我(https://medium.com/@hugeponkce)。
参考阅读:
https://medium.com/swlh/c-lean-code-db84f8e312d4
最后
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:
点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)
欢迎加我微信「qianyu443033099」拉你进技术群,长期交流学习...
关注公众号「前端下午茶」,持续为你推送精选好文,也可以加我为好友,随时聊骚。