重构的艺术

在吗?在吗?在吗?---》不要慌,我还在

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

一、重构的定义

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

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

二、重构的时机

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

三、代码坏味道

1)重复代码 2)过长函数 3)过大的类 4)过长参数列 5)发散式变化
6)依恋情结 7)霰(xian)弹式修改 8)数据泥团 9)基本类型偏执 10)switch惊悚(song)现身
11)冗赘(zhui)类 12)平行继承体系 13)夸夸其谈未来性 14)过度耦合的消息链 15)令人迷惑的临时字段
16)异曲同工的类 17)狎(xia)昵关系 18)中间人 19)纯稚的数据类 20)不完美的库类
21)过多的注释 22)被拒绝的遗赠

四、重构的方法

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

1、重新组织数据

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

重构的艺术_第1张图片

重构的艺术_第2张图片

重构的艺术_第3张图片

2)以对象取代数据值

重构的艺术_第4张图片

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

重构的艺术_第5张图片

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

重构的艺术_第6张图片

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

重构的艺术_第7张图片

重构的艺术_第8张图片

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

重构的艺术_第9张图片

重构的艺术_第10张图片

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

重构的艺术_第11张图片

重构的艺术_第12张图片

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

重构的艺术_第13张图片

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

重构的艺术_第14张图片

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

重构的艺术_第15张图片

2、在对象之间搬移特性

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

重构的艺术_第16张图片

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

重构的艺术_第17张图片

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

重构的艺术_第18张图片

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

重构的艺术_第19张图片

5)隐藏“委托关系”

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

重构的艺术_第20张图片

6)移除中间人

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

重构的艺术_第21张图片

重构的艺术_第22张图片

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

重构的艺术_第23张图片

8)引入本地扩展

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

重构的艺术_第24张图片

3、重新组织函数

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

重构的艺术_第25张图片

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

重构的艺术_第26张图片

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

重构的艺术_第27张图片

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

重构的艺术_第28张图片

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

重构的艺术_第29张图片

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

重构的艺术_第30张图片

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

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

重构的艺术_第31张图片

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

重构的艺术_第32张图片

重构的艺术_第33张图片

604b80ad02dd171a3f1fde0ef4579384.jpeg

9)替换算法

重构的艺术_第34张图片

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

4、简化条件表达式

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

重构的艺术_第35张图片

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

重构的艺术_第36张图片

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

重构的艺术_第37张图片

4)移除控制标志

重构的艺术_第38张图片

b94598d9e581e410e4f24dbdbc582d5f.jpeg

重构的艺术_第39张图片

重构为:

重构的艺术_第40张图片

重构的艺术_第41张图片

重构为:

重构的艺术_第42张图片

重构的艺术_第43张图片

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

重构的艺术_第44张图片

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

重构的艺术_第45张图片

7)引入Null对象

重构的艺术_第46张图片

8)引入断言

重构的艺术_第47张图片

5、简化函数调用

1)函数改名  rename method

重构的艺术_第48张图片

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

重构的艺术_第49张图片

3)移除参数

重构的艺术_第50张图片

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

重构的艺术_第51张图片

重构的艺术_第52张图片

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

重构的艺术_第53张图片

重构的艺术_第54张图片

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

重构的艺术_第55张图片

7)保持对象完整

重构的艺术_第56张图片

重构的艺术_第57张图片

重构的艺术_第58张图片

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

重构的艺术_第59张图片

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

重构的艺术_第60张图片

重构的艺术_第61张图片

重构的艺术_第62张图片

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

重构的艺术_第63张图片

重构的艺术_第64张图片

b8f177c791970ab09178aa965cc30bc5.jpeg

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

重构的艺术_第65张图片

11)隐藏函数

重构的艺术_第66张图片

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

重构的艺术_第67张图片

重构的艺术_第68张图片

引入工厂函数

重构的艺术_第69张图片

改进工厂函数

重构的艺术_第70张图片

进一步改进工厂函数

重构的艺术_第71张图片

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

重构的艺术_第72张图片

13)封装向下转型

重构的艺术_第73张图片

14)以异常取代错误码

重构的艺术_第74张图片

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

重构的艺术_第75张图片

6、处理概括关系

1)字段上移

重构的艺术_第76张图片

2)函数上移

重构的艺术_第77张图片

3)构造函数本地上移

重构的艺术_第78张图片

4)函数下移

重构的艺术_第79张图片

5)字段下移

重构的艺术_第80张图片

6)提炼子类

重构的艺术_第81张图片

7)提炼超类

重构的艺术_第82张图片

8)提炼接口

重构的艺术_第83张图片

9)折叠继承体系

重构的艺术_第84张图片

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

重构的艺术_第85张图片

11)以委托取代继承

重构的艺术_第86张图片

12)以继承取代委托

重构的艺术_第87张图片

7、大型重构

1)梳理并分解继承体系

重构的艺术_第88张图片

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

重构的艺术_第89张图片

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

4)提炼继承体系

重构的艺术_第90张图片

四、重构的本质

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

五、重构的阻碍

1、你不知道如何重构;

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

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

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

六、重写、补丁与重构

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

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

-----------》来自微信公众号 “老吕架构” 《----------

你可能感兴趣的:(设计模式,java,人工智能,面试,python)