《重构——改善既有代码的设计》读书笔记(二)

代码的 “坏味道”

1. 重复代码

重复代码大致分为以下几种:

a. 同一个类中不同函数含有相同的表达式。解决办法就是将两个函数相同的部分提炼为另一个函数接口,通过新增加的接口来实现之前的功能。

b. 两个互为兄弟的子类含有相同的部分。解决办法是将相同的部分提炼出来向上推,将这一部分推送至其共同的父类中。

c.两个无关的类中有相似的方法。解决办法是将这个方法单独提取成一个单独的函数,但需要根据实际情况考虑这个提取出的函数是应该单独封装成类还是放在其中一个类中,亦或是修改为全局函数等。

2.过长函数

处理时遵循的原则:每当感到需要写注释时,就将对应部分独立成一个函数。当遇到很多临时变量存储、传递值时,尽量将这些变量去除,而是以返回值或是取值函数将其替代。

3.过大的类;或者说功能过于复杂的类

处理原则:单个类尽可能只负责单项功能。界面类要与数据处理存储相关分离。

4.长参数列

处理原则:尽可能让参数减少,需要用到多个值时尽量使用接口去获取,而不是作为参数传递进来,因为这样修改时可以只修改获取参数的接口函数。

5.发散式变化

这个问题我的理解是说为了防止代码的可扩展性差,例如一个类添加需求A需要对其很多接口进行修改,如果再添加需求A’又需要对很多接口进行修改,那么这时首先应该想到的是对这个类进行抽象,将其作为一个基类,当面临不同的需求时通过继承扩展基类来实现先关的功能。

6.散弹式修改

这个与上一个相反,这种情况是当添加新的需求时,需对代码进行很多细小的改动,缺点是改动太多极容易遗漏。解决方法就是对这些相关属性、功能进行提炼,可以将多个相关的类似函数提炼为一个,也可以对多个类似的变量定义枚举或预定义变量等。

7.依恋情节

问题变现类似于将数据存储于数据处理放置在一起。解决方式是将其分离,或是将其放在相关使用最频繁的位置。

8.数据泥团

这个问题大概就是说多个数据绑在一起,处理使用都要一起,例如函数参数中的几个,如果删掉某一个参数有其他参数也变得无意义或无法正常使用,那么这些相关的参数就乱成了一团泥。结局方法就是将这些数据彻底糅合成一种新的数据,比如为其定义一种结构体、map、类等等。

9.基本类型偏执

这个问题是说很多程序员更偏向于使用多个基本类型变量,而不愿意为其组合,就像range一般人会使用两个int变量而不是为这两个int变量再去创建一个range类。

但是这个问题我觉得在基本类型变量不多或是组合后的类型用到的位置也不是很广泛的情况下,基本类型更方便一些,如果为了将两个int变量节省成一个的话而在工程中添加一个类似乎更加得不偿失。

10.switch惊悚

当switch判断的是类的类型时,可以将switch函数作为其基类的一个方法。

11.平行继承

问题表现为两个类相联系或是相互使用,导致对其中一个类继承或是改变时另一个类也不得不随着被改变。

12.冗余类

多余的代码要删掉,函数变量和类都要删

13. 盲目的未来性

现象为某些代码为了防止未来可能出现的某些现象和问题,添加各种复杂而又莫名其妙难以理解的代码。解决方式:删除不必要的对未知的处理,当然对未知异常捕获这种可以保留,但是绝对没必要在新需求或是想象中的bug出现前为其添加解决方案。

14. 复杂的临时字段

现象描述:某个成员变量并不是所有情况都能使用到,只有某些极端情况下才会出现。

作者推荐的解决办法是为极端情况创建一个单独的类似的类。

但是我觉得这样会让代码更为复杂也更容易在后来人修改时遗漏,但是为极端情况添加成员变量这种确实是不太好,可我也没想出什么太好的解决办法,如果我遇到这种情况的话我还是会加变量吧,但一定要写好相关的注释与文档。

15.过度耦合的消息链

简单来说就是两个对象通过多个中间商来发送消息。解决办法是先试着将想要获取的消息提炼为一个函数看能否通过一个函数取到,如果不行就从中间商中进行压缩,看能否去除一些中转的消息。

16.中间人

问题描述大概是一个类A的方法和变量再被另一个对象使用时,需要通过一个中间人来调用,但中间人身上的中转函数个数不多时还可行,但如果每个函数都要中间人转调那么这也是种病态的结构。

作者推荐的方法是吧中间人变成类A的子类。

但这样也不太适合于很多场景,我自己遇到过甚至前几天自己也刚刚就写了这样的代码,这种情况我也暂时没有想出解决方案。

17.狎昵关系:过于亲密

简单来说就是两个类对彼此都太过亲密,对彼此的内部都知道的太多了。一种解决办法是将两个类结合产生一个新的子类,这样对然不再狎昵但是权限更高了,也不太好哦;另一种就是修改两个类的功能与属性,强行斩断这种关系了。

18.异曲同工类

就类似于重复代码的问题。

19.不完美库

已有的库永远都是过时的库,所以已有的库永远都不可能会一直满足任何一个需求。当我们已有的库已经不能满足需要时,就去重写他,就算写出这个库的人是C++之父,他也可能会是过时的,重写就完了。

20.数据类

这种类只含有存储数据的变量与获取和改变这些变量值的函数。这种类最好是把对他数据的处理的相关代码整理一下到这个类上来,这样外界连数据都无需获取,可以直接根据需求调用接口得到结果就好了

21.被拒绝的遗赠

问题就是说子类继承父类时继承了自己不想要的东西。解决办法就是重新写一个正确的父类。

22.过多的注释

写注释不是坏事,但是一段代码出现了过多的注释说明这段代码肯定时段坏代码,因为只有让你难以理解的代码才会需要写一大堆注释来让其他人明白。

 

/*********************************************************/

这是这本书的第三章内容,其中有一些以前我没有当做问题来看待的情况,受教了,今晚就先看到这里。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值