【重构的目的】
重构的目的是消除代码的坏味道,使代码满足clean code.
常见的坏味道:
1、重复代码
2、函数功能不单一、超大函数
3、安全函数使用不规范,比如memcpy没判断返回值、未判断缓冲区的长度等
4、数据类型重新定义;比如typedef int DWORD
5、switch-case过多,圈复杂度高
6、代码各个模块耦合严重,测试困难
….
【clean code的标准】
好代码一般具备以下特质:
可读、安全、可靠、高效、可测试、可维护、可扩展
【软件设计原则】
这里主要说面向对象程序设计的原则,基础原则是实现高内聚低耦合;在此基础上有些软件专家提出了一些其他原则:
比如袁英杰提出的正交四原则:1、消除重复 2、分离变化 3、减少依赖 4、稳定依赖
此外还有Robert Martin提出SOLID原则,即
1、单一职责(SRP)
字面意思很好理解,但是容易被误解,过度强调职责的单一,但其本质上强调的是变化,即代码后续变化的方向是单一的;
2、开放封闭(OCP)
即对修改封闭,对扩展开放
3、里氏替换(LSP)
4、接口分离(ISP)
5、依赖倒置(DIP):也叫依赖反转或者控制反转(IoC),用于降低代码的耦合;即
代码应该依赖抽象,而不应该依赖具体实现和细节;高层模块不应该依赖底层模块,二者都有应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象;
这条原则是最难理解的,首先搞清楚几个概念:什么是依赖、什么是倒置(是不是有正置、正转..
举个例子:A类实现某个功能需要调用B类的方法,这就产生了依赖,即A依赖B;正常A中需要创建B的对象,调用B的方法,这即是正置或正转。
那么依赖倒置是指一般采用依赖注入(DI)的方式消除类之间的依赖,一般采取的方式是将B注册到容器中,A通过容器间接访问B;以前是A创建B,此处可以理解为是A主动获取资源,现在是B通过容器主动向A提供资源,即供需关系发生了变化,即为倒置。在代码层面,B注册到容器,容器管理B,A通过容器间接访问B(依赖B的抽象,不再依赖B的对象),从而减少了A、B之间的耦合。
此外,依赖倒置和依赖注入是同一概念站在不同角度的两种表述,依赖倒置是站在依赖关系的角度,依赖注入是站在资源获取方式的角度;
以上这些原则理解起来并不复杂,但是真正灵活掌握是一件很困难的事情,需要不断的实践,不断总结,才能将这些原则用于无形。就像张三丰教张无忌练太极剑一样,张三丰问张无忌还记得多少忌答道:全忘了。
同样的道理,当你进行重构的时候,不再思考要遵循某一种原则的时候说明你已经练成了,即无形中已遵循这些原则。
【重构的过程】
为保证重构不影响代码的功能,一般会首先构建测试防护 ,即构建测试用例(UT或者ST)。然后采取小步快跑的方法,每一步修改,跑通所有用例,保证每一步重构的正确性。
有些代码可能一开始由于依赖太多,很难构造测试用例,这时在构建防护 之前,要先抽取出接口类,将各个类抽取出来,使类之间依赖于抽象,而不是依赖于具体对象。
具体的过程如下:
1、抽取接口类,使程序可测试
2、提取公共接口
3、建立派生关系
4、构造测试对象,对于依赖的类,可以采用MOCK Objiect进行打桩;
5、编写测试用例;
6、采取一些重构手法,结合软件设计的原则,小步快走,不断迭代,完成重构的目的
【重构手法】
常用的重构手法:
1、抽:抽取方法,将实现具体功能的代码抽取为函数,实现功能单一;
2、替:采用内联方法消除重复代码
3、组:将方法归类,将对同一个数据对象进行操作的一些方法组合成功能类;
4、改:将子类中功能代码类似的方法重命名或者修改参数保留共性,为下一步移动做准备;
5、移:将子类都有的公共方法移动到父类;
【重构操作的十六字真言】
重构要非常小心,特别是无情重构,否则极易引入bug,破坏已有代码的功能,因此每一步修改要慎之又慎,不要步子跨的太大,要牢记并使用十六字真言:
1、旧的不变
2、新的创建
3、一步切换
4、旧的再见
以上每一步修改都要确保测试用例可以通过。
文章知识点与官方知识档案匹配,可进一步学习相关知识算法技能树首页概览34716 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!