提炼函数
时机:
当我们觉得一段大函数内某一部分代码在做的事情是同一件事,并且自成体系,不与其他掺杂时
当代码展示的意图和真正想做的事情不是同一件时候,如作者提到的例子。想要高亮,代码意思为反色,这样就不容易让人误解,印证了作者前面说的:当你需要写一行注释时候,就适合重构了
做法:
一个以他要做什么事情来命名的函数
待提炼代码复制到这个函数
检查这个函数内的代码的作用域、变量
编译查看函数内有没有报错(js可以通过eslint协助)
替换源函数的被提炼代码替换为函数调用
测试
替换其他代码中是否有与被提炼的代码相同或相似之处
关键字:
新函数、拷贝、检查、作用域/上下文、编译、替换、修改细节
内联函数
时机:
函数内代码直观表达的意思与函数名字相同
有一堆杂乱无章的代码需要重构,可以先内联函数,再通过提炼函数合理重构
非多态性函数(函数属于一个类,而这个类被继承)
做法:
检查多态性(如果该函数属于某个超类,并且它具有多态性,那么就无法内联)
找到所有调用点
将函数所有调用点替换为函数本体(非一次性替换,可以分批次替换、适应新家、测试)
删掉该函数的定义(也可能会不删除,比如我们放弃了有一些函数调用,因为重构为渐进式,非一次性)
关键字:
检查多态、找调用并替换、删除定义
提炼变量
时机:
一段又臭又长的表达式
在多处地方使用这个值(可能是当前函数、当前类乃至于更大的如全局作用域)
做法:
确保要提炼的表达式,对其他地方没有影响
声明一个不可修改的变量,并用表达式作为该变量的值
用新变量取代原来的表达式
测试
交替使用3、4
关键字:
副作用、不可修改的变量、赋值、替换
内联变量
时机:
变量没有比当前表达式有什么更好的释义
变量妨碍了重构附近代码
做法:
检查确认变量赋值的右侧表达式不对其他地方造成影响
确认是否为只读,如果没有声明只读,则要先让他只读,并测试
找到使用变量的地方,直接改为右侧表达式
测试
交替使用3、4
关键字
副作用、只读、替换变量
改变函数声明
最好能把大的修改拆成小的步骤,所以如果你既想修改函数名,又想添加参数最好分成两步来做。
不论何时,如果遇到了麻烦,请撤销修改,并改用迁移式做法)
时机:
函数名字不够贴切函数所做的事情
函数参数增加
函数参数减少
函数参数概念发生变化
函数因为某个参数导致的函数应用范围小(全局有很多类似的函数,在做着类似的事情)
做法(适用于确定了函数或者参数只在有限的小范围内使用,并且仅仅改名)
先确定函数体内有没有使用这个参数(针对于参数)
确定函数调用者(针对于函数)
修改函数/参数的声明,使其达到我们想要的效果
找到所有的函数/参数声明的地方将其改名
找到所有函数/参数调用的地方将其替换
关键字
使用变量者、函数调用者、修改函数、声明改名、调用替换
做法(标准化做法)
对函数内部进行重构(如果有必要的话)
使用提炼函数手法,将函数体提炼成一个新函数,同名的话,可以改为一个暂时的易于搜索的随意名字(如:aaa_getData,只要好搜索且唯一即可。),非同名的话,使用我们想要的名字作为新函数名字
在新函数内做我们的变更(新增参数、删除参数、改变参数释义等)
改变函数调用的地方(如果是新增、修改、删除参数)
测试
对旧函数使用内联函数来调用或返回新函数
如果使用了临时名字,使用改变函数声明将其改回原来的名字(这时候就要删除旧函数了)
测试
关键字:
内部重构、提炼新函数、好搜索的临时名字、变更、改变调用、旧函数使用新函数、改变调用名字
封装变量
时机:
当我们在修改或者增加使用可变数据的时候
数据被大范围使用(设置值)
对象、数组无外部变动需要内部一起改变的需求时候,最好返回一份副本
做法:
创建封装函数(包含访问和更新函数)
修改获取这个变量和更新这个变量的地方
测试
控制变量外部不可见(可以借助es6类中的get来实现不可变量以及限制可见)
测试
关键字:
新函数、替换调用、不可见