重构的艺术

在吗吗吗–》不要慌,我还在

经典重读:改善既有代码的设计

一、重构的定义

重构:对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

重构:使用一些列重构手法,在不改变软件可观察行为的前提下,调整其结构。

二、重构的时机

1、如果你发现自己需要为程序添加一个特性,而代码结构使你无法很方便的达成目的,那就先重构那个程序,使特性的添加比较容易进行,然后再添加特性。

2、重构前,先检查自己是否有一套可靠的测试机制。这些测试必须有自我检验能力。

3、重构技术就是以微小的步伐修改程序。如果你犯下错误,很容易便可发现它。

4、任何一个傻瓜都能写出计算机可以理解的代码。唯有写出人类容易理解的代码,才是优秀的程序员。

5、事不过三,三则重构。

6、不要过早发布接口。请修改你的代码所有权政策,使重构更顺畅。

7、当你感觉需要写注释时,请先尝试重构,试着让所有注释都变得多余。

8、确保所有测试都完全自动化,让它们检查自己的测试结果。

9、一套测试就是一个强大的bug侦听器,能够大大缩减查找bug所需要的时间。

10、频繁的运行测试。每次编译请把测试也考虑进去–每天至少执行每个测试一次。

11、每当你收到bug 告,请先写一个单元测试来暴露这只bug。

12、编写为臻完善的测试并实际运行,好过对完美测试的无尽等待。

13、考虑可能出错的边界条件,把测试火力集中在那里。

14、当事情被大家认为应该会出错时,别忘了检查是否抛出了预期的异常。

15、不要因为测试无法捕获所有bug就不写测试,因为测试的确可以捕获到大多数bug。

三、代码坏味道

四、重构的方法

大的分类共用7种类型  1)重新组织函数;2)在对象之间搬移特性;3)重新组织数据;4)简化条件表达式;  5)简化函数调用;6)处理概括关系;7)大型重构;

1、重新组织数据

1)自封装字段(不要直接访问一个字段,请使用取值和设置函数)

2)以对象取代数据值

3)将值对象改为引用对象(享元模式)

4)将引用对象改为值对象(上一条的反向动作)

5)以对象取代数组(更易读)

6、将单向关联改为双向关联(就像双向链表,某些情况下有奇效)

7、将双向关联改为单向关联(降低复杂度)

8)以字面量取代魔法数(常量的定义)

9)封装字段,面向对象三大特性之一:封装性

10)封装集合(用起来更方便)

2、在对象之间搬移特性

1)搬移函数(将函数放到最合适的位置)

2)搬移字段(将字段放到最合适的位置)

3)提炼类(类的单一职责原则)

4)将类内联化(与提炼类 相反)

5)隐藏“委托关系”

(兄弟们这不就是 迪米特法则吗,不要和陌生人说话,这就是中介者模式啊)

6)移除中间人

(这个就是和解除”委托关系“的意思,大量的委托也是有缺点的,所以要根据不同场景来灵活运用)

7)引入外加函数(在客户类中增加一个额外函数)

8)引入本地扩展

本质就是对已有类库进行扩展,两种方式  1)继承,在子类中增加额外扩展方法   2)使用组合的方式扩展(组合优于继承原则,装饰器模式、包装器模式、代理模式)

3、重新组织函数

1)提炼函数,这可能是最常用的重构手段之一:好处1)每个函数都像一个注释,有助于理解高层代码2)被复用的机会更大 3)函数的覆写更容易

2)内联函数(提炼函数的反向操作,用的机会不多)

3)内联临时变量,可以减少代码行数

4)以查询取代临时变量,提高代码复用的概率,但可能存在重复计算的性能问题,要根据实际情况选择

5)引入解释性变量,提高代码可读性

6)分解临时变量,临时变量被多次赋值,代码可理解性下降,出错概率会增加,还有入参一般都声明为final就是为了防止被重新赋值,导致出错概率增加

7)移除对参数的赋值,大佬写的代码,入参往往是final修饰的(一般用在长函数和复杂函数中,简单函数可以不考虑)

1)以临时变量取代对参数的赋值动作 2)为参数加上final修饰,强制遵守“不对参数赋值”的惯例

8)以函数对象取代函数,主要应对局部变量过多,提取函数需要过多参数的情况

9)替换算法

替换一个巨大而复杂的算法是非常困难的,只有先将它分解为较简单的小型函数,然后你才有把握进行算法替换工作。

4、简化条件表达式

1)分解条件表达式(提取函数呗)

2)合并条件表达式(提取函数呗)

3)合并重复的条件判断(逻辑想明白了才能写出更简洁的代码)

4)移除控制标志

重构为:

重构为:

5)以卫语句取代嵌套条件表达式(显然可读性更强)

6)以多态取代条件表达式(策略模式)

7)引入Null对象

8)引入断言

5、简化函数调用

1)函数改名  rename method

2)添加参数,增加参数的个数或者用对象替换参数

3)移除参数

4)将查询函数和修改函数分离(避免在一个查询函数中进行修改操作,函数职责要单一)

5)令函数携带参数(合并类似工作的函数)

6)以明确函数取代参数(和上一条“令函数携带参数”相反的操作,用在参数化并不能增加代码复用度的情况,这时候还不如分离开)

7)保持对象完整

8)以函数取代参数(减少不必要的传参)

9)引入参数对象(同时参数相关的行为也可以转移到参数对象中)

重构之后的效果:将参数提取到 DateRange对象中,并将相关行为 提取到DateRange对象中。

10)移除设值函数(当对象一旦创建后不希望再改变其内容,同时将字段设值为final类型,就将设值函数移除或者隐藏)

11)隐藏函数

12)以工厂函数取代构造函数

引入工厂函数

改进工厂函数

进一步改进工厂函数

以明确函数创建子类来代替工厂函数

13)封装向下转型

14)以异常取代错误码

15)以测试取代异常(提前校验参数的合法性)

6、处理概括关系

1)字段上移

2)函数上移

3)构造函数本地上移

4)函数下移

5)字段下移

6)提炼子类

7)提炼超类

8)提炼接口

9)折叠继承体系

10)塑造模板函数(模板方法设计模式啊)

11)以委托取代继承

12)以继承取代委托

7、大型重构

1)梳理并分解继承体系

2)将过程化设计转化为对象设计

3)将领域和表述/显示 分离(MVC设计模式)

4)提炼继承体系

四、重构的本质

就是使程序代码质量更高,可读性更强,应对需求变化的能力更强,修改扩展更轻松,延长软件的生命周期,创造更多的价值。

五、重构的阻碍

1、你不知道如何重构;

2、如果这些利益是长远的,何必现在付出这些努力呢远看来,说不定当项目收获这些利益时,你已经不在职位上了;

3、代码重构是一项额外工作,老板付钱给你,主要是让你编写新功能;

4、重构可能破坏现有程序;

六、重写、补丁与重构

重写整个程序是一种极端,一直凑合打补丁是另一种极端。

中庸之道是在软件开发与演进过程中及时的进行重构,消除代码坏味道与架构设计的不合理之处。?

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91536 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年6月12日
下一篇 2022年6月12日

相关推荐