【引言】《代码不朽》,书名全称《代码不朽:编写可维护软件的10大要则(Java版)》,作者:【荷】Joost Visser(约斯特·维瑟),英文原版名《Building Maintainable Software》,豆瓣读书评分7.7。(阅读周期: 2018.03.01 - 2018.08.15)
序言
序言中有一句很好的古语:“上医治未病,中医治欲病,下医治已病”(这么传统的国语风,想必是译者的发挥吧!);用到软件质量管理上,再合适不过了;我们经常说的要以客户为中心,客户最关注的想必也是产品的质量。
本书陆陆续续到半年之后的某天(2018.08.15),算是草草浏览完毕,真的仅仅是草草浏览,虽然书中说得很多道理都是很基本的,但是想把软件做好,这些原则也是必不可缺的基石和根本。
第1章:简介
软件质量的8个特征
- 可维护性
- 功能可适性
- 性能效率
- 兼容性
- 可使用性
- 可靠性
- 安全性
- 可移植性
可维护性基本原则
- 坚持简单的原则有助于提高可维护性
- 可维护性不是开发完成后才取考虑的,而应该是在项目开发的一开始就需要考虑,每一个人的贡献都需要计算在内(避免破窗效应)。
- 对各个原则的违背会带来不同的影响,有些严重程度甚于其他;一个软件系统越遵守原则,可维护性越高。(2-11章便是软件可维护性的十大原则)
第2章:编写短小的代码单元
基本原则
- 代码单元的长度应该限制在15行代码以内;
- 为此首先不要编写超过15行代码的单元,或者将长的单元分解成多个更短的单元,直到每个单元都不超过15行代码(还是有些难度的);
- 该原则能提高可维护性的原因:短小的代码单元易于理解、测试以及重用。
动机
- 短小的代码单元易于测试、分析和重用。
操作
- 适时的进行代码重构
- 将方法替换为方法对象(尤其是针对多参数的方法)
第3章:编写简单的代码单元
基本原则
- 限制每个代码单元分支点的数量不超过4个
- 考虑将复杂的代码单元拆分成多个简单的单元,避免多个复杂的单元糅合在一起
- 该原则对可维护性的提高很显而易见,主要是因为分支点越少代码单元越容易被理解、修改和测试
动机
- 简单的代码单元易于修改和测试
操作
- if、case、while、switch、for之类的分支嵌套都需要控制好层次
- 可考虑借用Map或者利用Java语言的多态性来精简链式条件语句
- 可考虑利用函数抽取或反条件return/break的方式,减少嵌套语句的嵌套层次
第4章:不写重复代码
基本原则
- 禁止复制代码;禁止复制代码;禁止复制代码;重要的事情说三遍
- 应编写可重用的、通用的代码;或者是复用已有的代码单元
动机
- 重复代码的分析和修改都更浪费成本
操作
- 有超过6行重复的代码或代码块,就必须考虑提取以解决重复性
- 处理的方式:类的继承、提取出公共工具
- 善用第三方工具(比如Apache本身有很多工具封装),不要重复造轮子
- 不要认为重复字符串就不需要重构,实际也是很有必要的(比如sql里面的关键词)
第5章:保持代码单元和接口简单
基本原则
- 每个方法的参数尽量控制在不超过4个
- 参数过多时,尽量使用对象封装
动机
- 短接口更易于理解和重用
- 短接口的方法更易于修改
操作
- 必须时刻牢记控制接口参数的数量
- 对默认值进行方法重载(比如:JDK里的很多集合类,有很多不同的重载构造方法)
- 单一职责原则,就是一个方法尽量只做一件事,流程主方法负责串联流程,每个方法要做到责任明确
第6章:分离模块之间的关注点
基本原则
- 避免形成超大型的模块,便于实现模块之间的松耦合
- 类的职责尽量要单一化,简单明了;不要将不同职责糅合到一个模块,尽量做好职责划分
- 面向接口,通过接口屏蔽实际实现
动机
- 小型、松耦合的模块允许开发人员独立进行工作(便于工作划分)
- 小型、松耦合的模块降低了浏览理解代码的难度
- 小型、松耦合的模块避免让新人赶到手足无措和焦虑
操作
- 避免写超大的类,可以考虑根据不同的关注点将一个大类拆分成多个小类
- 可利用很多第三方库或框架来替换自己写的代码,毕竟它们的稳定性和可靠性是经过验证的(StringUtils、FileUtils等很多不同的Utils)
第7章:架构组件松耦合
基本原则
- 顶层组件之间应该做到松耦合
- 尽可能的减少当前模块中需要暴露给(例如:被调用)其他组件中模块的相关代码
动机
- 低组件依赖允许独立维护,不依赖于整个系统
- 低组件依赖可以分离维护职责
- 低组件依赖让测试变得更容易
操作
- 限制作为组件接口的模块的大小
- 做更高层次的抽象
- 避免使用透传调用(避免对其他组件接口模块的直接调用)
- 注意设计模式的使用(比如:抽象工厂)
第8章:保持架构组件之间的平衡
基本原则
- 需要平衡代码中顶层组件的数量和体积;也就是要保证组件平衡性
- 应该保持源代码中的组件数量接近于9(比如:6-12),并且要保证组件的体积基本一致
动机
- 好的组件平衡能让查找和分析代码更容易
- 好的组件平衡能隔离维护所带来的影响
- 好的组件平衡能分离维护职责
操作
- 确定将功能合成组件的合适原则,不要盲目的合成
- 明确系统的领域并一直坚持下去
第9章:保持小规模代码库
基本原则
- 保持代码库的规模尽可能小
- 控制代码库的增长,并且必要的情况下要主动减少系统的代码体积
动机
- 以大型代码库为目标的项目易失败
- 大型代码库的维护难度更高
- 大型系统会出现更密集的缺陷
操作
- 控制需求的蔓延
- 不要复制粘贴代码
- 适时重构已有代码
- 使用第三方库和框架
第10章:自动化开发部署和测试
基本原则
- 需要对你的代码进行自动化测试
- 尽量通过测试框架来编写测试代码
动机
- 自动化测试让测试可重复
- 自动化测试会让开发更有效率
- 自动化测试让代码行为可预测
- 测试实际是对被测代码的一个补充文档
- 编写单元测试用例能让你编写更好的代码
操作
- Junit
- 编写单元测试必须严谨(正常、非正常;保持测试的独立性)
- 保证测试覆盖率
第11章:编写简洁的代码
基本原则
- 代码必须保持简洁
- 不应该在完成开发工作后留下代码坏味道(“离开营地时,要让它比来时更干净”)
操作
- 不要编写单元级别的代码坏味道
- 不要编写不好的注释
- 不要注释代码
- 不要保留废弃代码
- 不要使用过长的标识符命名
- 不要使用魔数常量
- 不要使用未正确处理的异常(禁止吞噬异常);尽量按照特定异常多次捕获;特定异常特定返回
第12章:后续事宜
- 将前面所有原则变成实践
- 低层级(代码单元)的原则要优先于高层级(组件)的原则
- 每个人都需要对自己每次提交的代码的质量负责,个体的优化是整体优化的前提
后记-2019.02.21
今天大约是写完这篇文档的半年后了,最近有一段时间没怎么写东西了,一来是前段时间比较忙,二来最近多数空闲时间在思考一些方向;今天抽了点小空把当初记录的这篇《代码不朽》的摘录又过了一遍,愈发深切的体会到“大道至简”这句话的深意。把复杂的东西简单化,才是我们作为技术从业者的终极追求吧!
今天早上看了一个日本作家的关于阅读技巧的书籍,提到了flow式的阅读体验,在此实践了一下,这一次留下的总体印象大体可以概括为以下几个词:短小、简洁、不重复、复用。希望一段时间之后会有一些新的体会吧!