重构智库

出自《软件之道:软件开发争议问题剖析》第 23 章

预测缺陷代码覆盖率代码变动代码复杂度代码依赖人员以及组织指标社会网络/综合指标正确的测试代码代码覆盖与使用模式的匹配度代码覆盖时的复杂度变动代码行数/总代码行数删除代码行数/总代码行数变动文件数/总文件数代码变动次数/变动文件数代码变动所耗周数/文件总数代码改动总行数/代码变动所耗周数变动代码行数/删除代码行数代码改变总行数/代码变动次数代码行数圈复杂度扇入扇出函数数量继承深度耦合子类数数据依赖调用依赖工程师数量(NOE)前工程师数量(NOEE)二进制修改频率(EF)主负责人尝试(DMO)组织参与开发率(PO)组织级代码负责等级(OCO)总体组织负责度(OOW)组织交叉因子(OIF)规模连结配对密度弱模块标准化模块两步区域到达效率中间人标准化中间人自我的中介度

不同软件指标模型总体准确率

模型查准率查全率
组织结构86.2%84.0%
代码变动78.6%79.9%
代码复杂度79.3%66.0%
社会网络/综合指标76.9%70.5%
依赖关系74.4%69.9%
代码覆盖率83.8%54.4%

工具:

为什么重构?

重构的动机

重构不一定能带来什么?

重构是一种文化

大规模重构的时机

说清重构的价值

系统重构模式与原则

重构模式:IPDCA

四级重构

小步前进

Git 工作流

  • Master 机制
  • PR 机制

建立远景与方向

拉通:对齐目标

明确潜在风险

人评估

重构范围

产出物

  • KPI 度量
  • 重建规范
  • 团队赋能
  • 原则与模式

重构评估与度量

识别技术债务

  • 技术债风暴
  • 架构评估:技术驱动 vs 业务驱动
  • 代码评估:收集 bad smell
  • 收集 Todo
  • 测试和文档评估

项目评估

编写工具评估

代码评估工具

真实的测试覆盖率

可测试性评估

度量

寻找专业人士

重构准入条件

工具准备

重构看板

版本控制

自动化重构工具

持续集成环境

记录

探索性重构:可行方案

准备知识:坏味道的模式

  • C4 模型

探索模式

    • 从分层架构到具体代码
    • 从外部适配器到内部适配器
    • 查看测试情况
    • 针对于最复杂的情形和最简单的情形
  • 工具:API 列表和调用关系

构建领域知识

  • 了解业务架构
  • 架构全景
  • 领域名词表

寻找高引用 + 高修改

第一步:防护网

防护网策略

第一个测试

持续集成重构

检视测试

系统架构重构

高质量级 DDD 重构:演进驱动的事件风暴

轻量级 DDD 重构:现状驱动的领域方案

限界上下文要素

微服务重构

服务架构重构

整洁架构

设计新架构

实施新分层架构

  • 划分类,移动代码
  • 技术模块化 => 重搭

中间态分层

验收条件:构建

潜在问题

  • bean 注入
  • 解决冲突
  • 同步 API 修改
  • 对齐新分层架构

公共代码重构

它真是个 util 吗?

过度设计

重新定义:消除二义性

类进行内聚

划分技术部分

划分业务部分

  • 职责少 => 平级
  • 业务代码多 => 再按业务拆分

模块重构

组件聚合三原则

打破包之间的依赖关系

依赖倒置

  • 更好的面向对象

清理垃圾代码

模型重构

聚合行为

  • 由内到外剥离,由外到内聚合
  • 识别模式 1:输入参数
  • 识别模式 2:返回参数
  • 优化创建

重命名:统一语言

  • 状态
  • 方法
  • 容器

离心分离模型:消除二义性

提取参数对象

处理过程逻辑

领域特定语言

模式重构

终止 Singleton

工厂封装复杂构建

  • 重构手法

策略模式提供易变规则

建造者模式拆解复杂对象

工具:自动化识别

代码重构

降低圈复杂度

手法:提取

手法:内联

手法:移动

  • 方法移至其它类中

标准:4 行的方法

重构示例

评估

  • C4 模型展开

工具评估

  • 代码统计
  • 基本情况评估
  • 代码坏味道评估
  • 架构评估
  • API 评估
  • API 架构图
  • 高引用 + 高修改分析
  • 没有测试

重构策略

架构重构

分层重构

模型重构

代码重构

自动化重构

数据库重构(TBC)

数据库回归测试:数据不变性

  • 前测试
  • 后测试

引入数据库迁移工具

迁移源数据

汲取式重构:存储过程转换

重构之后:工具的问题

架构守护

  • 架构守护测试
  • 坏味道守护

测试驱动开发

完善基础设施

重构之后:解决人的问题

代码写得烂

养成优秀的开发习惯

人员能力提升

  • 练习项目
  • 培训教程
  • 典型问题

重构之后:流程的问题

流程优化

需求规范化

  • 实例化需求
  • 行为驱动开发(BDD)

重构之后:提炼知识

知识仓库

重建知识仓库

问题是什么?

为什么我们需要重构?

自动化重构

前端自动化重构

在我之前写的那篇『重构的自动化』中,介绍了如何去做这样的工具:

  1. 构建特定语言的语法解析器。
  2. 设定代码坏味道的内容及标准。
  3. 针对于每一项坏味道,编写识别代码。
  4. 编写代码坏味道的建议改进和实施代码。
  5. 实现坏味道的自动化重构。

以 Vue 为例,这个过程便是:

  1. 寻找适用于 Vue 的 AST 生成工具。如 eslint-vue-parser
  2. 寻找和编写适用于 Vue 编码的相关规范。
  3. 对应规范寻找代码中的问题。
  4. 针对该问题寻找改进点
  5. 实现自动化重构

JavaScript

如果只是针对于简单的 JavaScript 重构来说,我们可以考虑使用 jscodeshift 这一类的工具。jscodeshift 是一个工具包,用于在多个 JavaScript 或TypeScript 文件上运行 codemods(自动代码修改)。

当然了,如果你不嫌麻烦的话,还可以使用类似的工具:

SourceEsprima 4.0.1[UglifyJS2](https://github.com/mishoo/UglifyJS2)[Traceur](https://github.com/google/traceur-compiler)[Acorn](https://github.com/marijnh/acorn) 8.0.4[Shift](https://github.com/shapesecurity/shift-parser-js)[Shift (no early errors)](https://github.com/shapesecurity/shift-parser-js)
jQuery.Mobile 1.4.2149.6 ±1.8%170.7 ±1.2%178.2 ±6.0%214.4 ±13.0%429.5 ±13.5%203.9 ±9.6%
Angular 1.2.5125.0 ±2.8%138.2 ±2.9%134.5 ±2.3%113.8 ±2.8%251.5 ±1.3%147.1 ±1.5%
React 0.13.3127.2 ±1.0%158.2 ±1.4%160.0 ±0.8%128.5 ±2.8%310.8 ±2.7%182.6 ±2.7%
Total401.8 ms467.0 ms472.7 ms456.7 ms991.9 ms533.5 ms

嗯,原理都是相似的。

TypeScript

官方提供了 AST 解析。

从我的之前写的前端架构守护工具:https://github.com/phodal/dilay,你就可以看到相似的代码。

CSS

针对于 CSS 重构来说,相似的工具有:https://github.com/csstree/csstree

不过,我们建议你们使用 Lemonj(使用 Antlr 进行语法树解析):https://github.com/twfe/lemonj

框架特定

针对于 Angular,官方提供了 Angular Schematics,除了自动代码修改,还可以做各种自动化升级工作。

针对于 Vue,官方也有类似的工具:https://github.com/vuejs/vue-codemod

针对于 React,官方也有工具:https://github.com/reactjs/react-codemod

结合 CLI 工具

当我们修改完代码之后,下一步要做的事情就是修改文件,这里推荐一下:schematics-utilities,虽然是 Angular 上下游的工具,但是它不限于框架。

有了这个工具,我们就可以快速修改代码,如:

recorder = tree.beginUpdate(path);

recorder
    .remove(start, length)
    .insertLeft(start, value);

tree.commitUpdate(recorder);

这些都大同小异,没有什么特别之处。

重构到微服务

未来

追求技术卓越。

推动个人变革,进而引领组织变革

整理知识,加强教育

在整个流程中将价值创造最大化