RedRain的简书:http://www.jianshu.com/users/29e03e6ff407/latest_articles
一.创建
1. 如果类中有太多的构造函数,客户要弄清应该调用其中的哪一个会非常困难.
- 方法之一是应用
提炼类
或提炼子类
这样的重构, 减少构造函数的数量. - 方法之二是通过用
Creation Method替换构造函数
重构来澄清构造函数的意图.
2.如果对象创建过程中使用的数据和代码在许多类中都存在
-
将创建知识搬移到Factory
重构可以把创建代码和数据合并为一个Factory来减少创建代码的蔓延.
3.如果类层次中有多个类都类似地实现了一个方法, 只是对象的创建步骤不同
- 首先通过用
Factory Method
引入多态创建
重构来删除重复代码.
4.确保客户代码通过一个公共接口与多个类的实例进行通信
- Factory封装类
5.简化对象结构的构造
- 用Builder封装Composite重构说明了如何用Builder模式提供构造Composite模式的更简单而且不易出错的方式.
二.简化
为了使代码简单,必须要思考它复杂在什么地方, 并要不停地问:"怎样能更简单一些?"
通常情况下, 可以考虑一种完全不同的解决方案来简化代码. 这里展示了简化方法
,状态转换
和树型结构
的不同方案.
1.更有效地表达方法实现的功能以及如何实现这些功能
-
组合方法
重构用来生成更优雅的方法 - 一个组合方法由对一些命名良好的方法的调用组成
- 这些方法数据实现细节的同一个曾铭.
2.算法经常会因为多种变化而变得复杂
- 用
Strategy替换条件逻辑
重构展示了如何通过把算法分解成单独的类来简化它. - 如何算法并没有复杂到需要使用Strategy,只会使设计更加复杂
3.一个类中有过多的特殊情况或装饰逻辑
-
将装饰逻辑搬移到Decorator
重构描述了如何判断是否需要应用Decorator, 并展示了如何把装饰功能从类的核心职责中分离出来.
4.控制状态转换的逻辑往往会变得越来越复杂.
- 用
State替换状态改变条件语句
重构描述了如何简化复杂的状态转换逻辑, 并帮助确定逻辑是否复杂到应该应用State模式
5.针对树型结构的重构方法
- Composite替换隐含树, 展示了Composite模式如何能够简化客户程序对树形结构的创建和交互
6.完全简化一个用来控制哪组行为应该执行的switch语句
- 用Command替换条件调度程序.
三.泛化
泛化是把特殊代码转换成 通用目的 代码的过程. 泛化代码的产生往往是重构的结果. 其最常见的动机就是去除重复代码, 其次是为了简化或澄清代码.
1. 去除同一类层次结构中子类所包含的相似方法中的重复代码.
-
Template Method
重构,如果这些方法基本是遵循一定的步骤, 一定的顺序, 即使这些步骤有少许区别, 也可以通过在超类中定义Template Method把这些区别与泛化的内容分开
2.一个类层次结构中存在不恰当的Composite[组合]实现的时候.
-
提取Composite
重构是提炼超类重构的具体应用, 通过把Composite提取成超类, 子类就可以共享Composite的一个泛化实现.
3.如果系统含有处理一个对象代码, 同时又含有处理一组相同对象的代码(通常是某个集合).
- 用
Composite替换一/多之分
重构可以帮助我们产生一个泛化的解决方案, 可以无差别处理一个或多个对象
4.负责通知的对象和被通知的对象紧紧的耦合在一起.
- 用
Observer替换硬编码的通知
重构是用泛化替代特定方案的经典实例.为了允许其他类的实例也可以被通知, 我们可以把代码重构成使用Observer.
5.当客户代码使用不同的接口与相似的类交互时, 往往就会产生复杂的处理逻辑.
- 应用
通过Adapter[适配器]统一接口
重构, 客户代码就可以通过一个泛化的接口与相似类交互, 这就为去除客户代码中重复处理逻辑的其他重构铺平了道理.
6.当一个类作为组件,类库,API或其他实体的多个版本的Adapter的时候, 这个类就会包含重复代码, 并且设计也不会简单.
- 应用
提取Adapter
重构可以产生实现了通用接口并适配单一版本代码的类.
四.保护
有些重构能够改进对现有代码的保护, 但不能改变现有代码的行为. 应用这些重构的动机可能是改进对现有代码的保护, 或者是标准的重构动机, 如减少重复代码或简化澄清代码.
1.用类替换类型代码
2.如果想要控制一个类被实例化多个对象, 减少内存使用量或改进性能.
- 用Singleton限制实例化.
- Singleton模式的一个很不好的动机是使一段代码能够访问很难到达的信息. 一般情况下, 只有在性能分析程序告诉你值得这么做的时候,才会用到
Singleton限制实例化
3.如果代码中包含很多的逻辑来检查相同的null值.
- 引入Null Object重构可以帮助我们使用另一个方式让代码避免使用null值. 从而简化代码.
五.聚集操作
Collecting Parameter是这样一个对象, 他会访问不同的方法, 以便从中聚集信息, 被访问的方法可能处于一个或多个对象中. 每个被访问的方法都会为Collecing Parameter提供信息. 在访问了所有的相关方法之后, 我们就可以从Collecting Parameter中获取聚集的信息.
1.当你拥有一个很长的,包含很多行为来聚集信息的代码的方法时.
- 利用
将聚集操作搬移到Collecting Parameter
重构与组合方法
重构一起使用, 会达到最好的效果. 应该把接收并写入Collecting Parameter的代码提炼成方法, 这样就可以把原方法分解成几个小部分, 每一部分处理聚集的一小块.
2.Visitor模式
Collecting Parameter模式的能力是从几个对象中聚集信息, 从这一点上来看, 它和Visitor模式很相似. 不同的是
- 被Visitor访问的对象把自己传入Visitor的实例.
- 被Collecting Parameter访问的对象通过简单地调动Collecting Parameter上的方法来为它提供信息.
Visitor模式只适用于从多个对象中聚集信息, 而不适用于一个对象的情况. 它也更适用于从不同的对象中聚集信息, 而不适用于相似的对象(例如,共享相同接口的对象). 因为Visitor实现起来要比Collecting Parameter复杂. 所以要使用Visitor之前先考虑是否可以使用Collecting Parameter.
六.实用重构
1.使构造函数彼此调用,去除构造函数中重复代码.
-
链构造函数
, 这个重构会在用Creation Method替换构造函数
重构中用到
2.当需要一个超类或接口来共享子类的相同接口时.
-
统一接口
重构就可以派上用场. 应用这一重构的通常动机是能够多态地使用对象.重构将装饰功能搬移到Decorator
和将聚集操作搬移到Visitor
都会使用到这一重构
3.一个字段被赋值为局部实例化的值, 而你更希望把这个值作为参数传递进来.
- 使用
提取参数
重构. 这在很多情况下都是很有帮助的, 尤其是将装饰功能搬移到Decorator
重构, 他会在应用了以委托取代继承
重构后, 马上使用这一重构.