《重构改善既有代码的设计 》读书笔记之代码坏味道

1、什么是坏味道

观察代码的时候,我们会找寻出某些特定的结构,而这些结构指出了重构的可能性,这种结构也称坏味道。在本章我着重总结坏味道的概念,至于相关的重构手法后续补充,表示还没看。Java中字段(field),通常叫做“类成员”,或 “类成员变量”,有时也叫“域”,理解为“数据成员”,用来承载数据的。

2、Duplicated Code(重复代码)

重复代码及在一个地方以上出现相同的代码结构,而要做的是想办法合二为一。

  1. 情形一:同一个类的两个函数含有相同的表达式。提炼函数的方法提炼出重复代码,然后把两个地点都调用提炼的一段代码。
  2. 情形二:两个互为兄弟的子类含有相同的表达式。都使用提炼函数的方法,把提炼的代码推入超类。如果不完全相同,则把用提炼函数把相同与差异的部分分开,构成一个独立的类,然后运用塑造模板函数。如果只是不同算法做同样的事,可以用替换算法解决。
  3. 情形三:两个不相关的类。提炼类的方法将重复代码放入独立的类中。
3、Long Method(过长函数)

程序越长越难理解,应该更积极地分解函数。有一条原则:每当感觉需要一注释来说明点什么的时候,我们就把需要说明的东西写入一个独立的函数中,并以其用途命名。

4、Large Class(过大的类)

行数过多的类。

5、Long Parameter List(过长参数列)

太长的参数列表难以理解,太多参数导致前后不一致、不易使用,修改又不方便。如果将对象传递给函数,大多数修改变得没必要。

6、Divergent Change(发散式变化)

如果某个类经常因为不同的原因在不同的方向上发生了变化,Divergent Change就出现了。针对某一外界的变化的所有相应的修改,都应该发生在同一个类中,而这个新类的所有内容都应该反应此变化。

7、Shotgun Change(霰弹式修改)

如果没遇到某种变化,你都必须在许多不同的类中做出许多小修改,这个坏味道就是Shotgun Change,如果修改的代码散布四周,不但很难找到他们且很容易忘记。

8、Feature Envy(依恋情结)

函数对某个类的兴趣高于对自己所处的类的兴趣。如我们经常看到某个函数为了计算某个值,从另一个对象那儿调用了几乎半打的取值函数,可以把这个函数移至另一个地点。

9、Data Clumps(数据泥团)

常常可以在多个地方看到相同的三四项相同的数据:两个类中相同的字段、许多函数签名中相同的参数(如:A(a, b)与B(a, b))。这些数据应该有属于他们自己的对象.

10、Primitive Obsession(基本类型偏执)

对象技术的新手通常不愿意在小任务上运用小对象–像结合数值和币种的money类、由一个起始值和一个结束值组成的range类、电话号码或邮政编码等特殊字符串,可将原本的数据替换为对象,从而走出传统的洞窟,进入炙手可热的对象世界。

11、Switch Statements(switch惊悚现身)

面对对象程序的一个最明显特征是:少用switch语句。从本质上说,swtich语句的问题在于重复。你通常会发现同样的switch语句散布于不同地方。如果要为它添加一个新的case子句,就必须找到所有switch语句并修改它们。面对对象中的多态概念可带来优雅的解决方法。

12、Parallel Inheritance Hierarchies(平行继承体系)

每当你为某个类增加一个子类,必须也为另一个类相应增加一个子类。如果你发现某个继承体系的类前缀和另一个继承体系的类名称前缀完全相同,便闻到了这种坏味道。

13、Lazy Class(冗赘类)

如果一个类的所得不值自己的身价,它就应该消失。项目中常常会出现这样的情况:某个类原本对的起自己的身价,但重构使他身形缩水,不再做那么多工作;或者开发者事先规划了某些变化,并添加一个类来应对这些变化,但变化实际没有发生。

14、Speculative Generality(夸夸其谈未来性)

当有人说“噢,我想我们总有一天需要做这些事”,并因此企图以各种各样的钩子和特殊情况来处理一些非必要的事情,这种坏味道就出现了。往往导致系统更难理解和维护。如果装置用不到就不值得。

15、Temporary Field(令人迷惑的暂时字段)

有时你会看到这样的对象:其内的某个实例变量只为某种特定情况而设。这样的代码让人不易理解,因为你通常认为所有时候都需要它的所有变量。
改法有二:

  1. 把所有和这个变量相关的代码放入一个新类中
  2. 在变量不合法时创建一个NULL对象,避免写出条件式代码。
16、Message Chains(过度耦合的消息链)

如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象…这就是消息链。意味着客户代码将与查找过程中的导航结构紧密耦合。一旦对象间关系发生任何变化,客户端不得不做出相应的修改。

17、Middle Man(中间人)

对象的基本特征之一是封装–对外部世界隐藏其内部细节。封装往往伴随委托。比如说你问主管是否有时间参加一个会议,他就把这个消息“委托”给他的记事簿,然后才能回答你。
但是人们可能过度使用委托。你也许可能在某个类接口看到有一半的函数都委托给其他类,这就是过度运用。这时可以使用移除中间人手法。

18、Inappropriate Intimacy(狎昵关系)

狎昵–指过于亲近而态度不庄重。
有时你会看到两个类过于亲密,花费太多时间去探究彼此的private成分。如果这发生在两个“人”之间,我们不必做卫道士;当对于类,我们希望它们严守清规。

19、Alternative Classes with Different Interfaces(异曲同工类)

如果两个函数做同一件事,却有着不同的签名。

20、Incomplete Library Class(不完美的库类)
21、Data Class(纯稚的数据类)

这些类有一些字段,以及用于访问这些字段的函数,除此之外一无长物。这样的类只是一种不会说话的数据容器,它们几乎一定被其他类过分细琐地操控着。

22、Refused Bequest(被拒绝的馈赠)

如果子类复用了超类的行为,却不愿意支持超类的接口,拒绝馈赠的坏味道就会变得浓烈。拒绝继承超类实现,不介意;但如果拒绝继承超类的接口,我们不以为然。应该使用以委托替代继承手法达到目的。

23、Comments(过多的注释)

常常你会发现有这样的情形:你看到一段代码有着长长的注释,然后发现之所以注释存在是因为代码很糟糕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值