Refactoring Study Notes

Refactoring Study Notes

一月 19, 2019 阅读 73 字数 2304 评论 1 喜欢 1

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

重构技术以微小的步伐修改程序,因为每次修改幅度很小,任何错误都可以轻易检查出来,并作出修正

何时该重构?

事不过三,三则重构

这个阶段重点学习重构技巧,记录或者总结一下学习到的技巧

1.3分解并重组:对函数的提取

任何不被修改的变量可以当做参数传入,需要修改的可当做返回值传出,当然也可以用指针当做参数传入,不需要返回值,而当修改数量多的情况,就要考虑定义一个类或者结构体了

设计完函数原型后,对函数内的变量应该相应改变其变量名,使其阅读容易

1.4运用多态取代与switch的条件逻辑

假如子类拥有父类的同类型属性,比如Movie有Price这个属性,而Movie分为ChildrenMovie和AdultMovie,这两个子类分别有自己的Price,可以把Price抽象为一个抽象类AbstractPrice,把ChildrenMovie和AdultMovie的Price各自抽象为一个类去继承它,这里使用了State模式

3.代码的坏味道

3.1Duplicated Code重复的代码

一种常见的情况是”两个互为兄弟的子类内含相同的表达式”,可以将这部分代码放到父类.如果代码只是相似,可以运用Template Method将差异的部分单独构造一个函数.

3.2 Long Method过长函数

如果有太多的临时变量和参数,可以把这个Method提升为一个单独的Class

3.3Large Class过大的类

可以将几个相关的变量提炼到新的类内

3.4Long Parameter List过长的参数列

可以构造”参数对象”

可以Replace Parameter with Method,即写一个不需要参数的Member Function去取代原来函数所做的事情

3.5Divergent Change发散式变化

“一个类受多种变化的影响”,某个类因为不同的原因在不同的方向发生变化.比如新加一个数据库,需要改变若干个函数.为此,应该找出某特定原因而造成的所有变换,提炼到新的类

3.6Shotgun Surgery散弹式修改

“一种变化引发多个类相应修改”,类似Divergent Change,但恰恰相反,遇到某种变化,必须在许多不同的类内做出许多小修改.这种情况,可以把所有需要修改的代码放进同一个类.

3.7Feature Envy依恋情结

类内某个函数对其他类的依赖高于所处的类,可以将总是一起变化的东西放在一块,放到它感兴趣的类内,如果变化出现例外,我们就搬移那些例外的行为,保持变化只在一地发生.Strategy和Visitor模式可以是修改函数的行为轻而易举,但是要付出多一层间接性的代价.

3.8Data Clumps数据泥团

两个类中相同的字段,函数签名相同的参数,将他们提炼到一个独立的对象,然后简化函数调用,在着手寻找Feature Envy

3.9Primitive Obsession基本类型偏执

积极使用小对象,如:发现一组经常放在一起的字段,在参数列看到基本类型,从数组中挑选数据

3.10Switch Statement条件选择Switch

运用多态替换switch,可以将switch单独提炼到一个函数,再搬移到需要多态性的那个类内,在以其他手法处理各种case,是使用子类来表达,还是使用State/Strategy.

如果运用多态显得杀鸡焉用牛刀,可以Replace Parameter with Explicit Methods,如果case选项有NULL,可以使用Introduce Null Object.

3.11Parallel Inheritance Hierarchies平行继承体系

系Shotgun Surgery的特殊情况,每当为一个类增加子类,必须为另一个类增加子类.可以让一个继承体系的实例引用另一个继承体系的实例.

3.12Lazy Class冗赘类

Inline Class处理

3.13Speculative Generality夸夸其谈未来性

Inline Class处理

3.14Temporary Field令人迷惑的暂时字段

某个变量仅仅为某种情况而设,提炼到新的类吧,例如,类内的某个算法使用了好几个变量,但这些变量别无它用

3.15Message Chains过度耦合的消息链

通过一个对象请求另一个对象,再如此反复请求.一旦对象间的关系发生变化,难以修改.可以使用Hidden Delegate,但这样会把一系列的对象变为Middle Man,更好的选择是,找到最后得到的对象用来干什么,在把使用该对象的代码提炼到一个独立的函数,推入消息链

3.16Middle Man中间人

封装往往伴随着委托,如果某个类一般的接口都委托给了其他类,就是过度使用委托,可以使用继承把它变为实责对象的子类

3.17Inappropriate Intimacy狎(xia4)昵关系

两个类过度关注彼此的private成分,可以合并为新类,或者产生新的类来当传递信息

3.18Alternative Classes with Different Interfaces异曲同工的类

合并或者加入继承体系

3.19Incomplete Library Class不完美的库类

Introduce Foreign Method或者Introduce Local Method

3.20Data Class纯稚的数据类

3.21Refused Bequest被拒绝的遗赠

子类复用了父类的行为,却不愿意支持父类的接口,应该运用Replace Inheritance with Delegation

3.22Comments过多的注释

用函数名代替注释

评论列表

发表评论

电子邮件地址不会被公开。