1 依恋情节(Feature Envy)
如果某个函数为了计算某个值,从另一个对象调用比较多的取值函数,这个时候,应该使用Move Method(搬移函数)
把它移到它该去的地方。如果函数中只有部分受到这种依恋之苦,则先使用Extract Method(提炼函数)
把这一部分提炼到独立函数中,然后再进行Move Method(搬移函数)
。
特例:策略模式(Strategy),访问者模型(Visitor),这两者是为了对抗发散式变化(Divergent Change)
坏味道。一般数据和对应的行为是一起变化的,如果不是,则搬移那些行为,保持在一地发生。这两种模式使得你可以轻松修改函数行为,因为它们将少量需要被覆写的行为隔离开来,代价是:多了一层间接性。
2 过渡耦合的消息链(Message Chains)
即过长的函数调用链。可以使用Hide Delegate(隐藏委托关系)
做恰当的处理(理论上可以重构消息链上的任何一个对象,但是会把一系列对象都变为中间人)。
可以观察下消息链最终得到的对象是干嘛的,能否用Extract Method(提炼函数)
把使用该对象的代码提炼到一个独立函数中,再用Move Method(搬移函数)
把这个函数推入消息链(如果链上的某个对象有多位客户打算航线此航线的剩余部分,就加一个函数来做这件事)。
3 中间人(Middle Man)
为了隐藏对象内部层次关系细节,往往会使用委托,即中间人。
过渡使用委托:某个类接口有一半的函数都委托给其他类,这既是过度运用了。这个时候可以使用Remove Middle Man(移除中间人)
,直接和负责的对象打交道。
如果这样的委托函数只有几个,可以使用Inline Method(内联函数)
把他们放入调用端。
如果中间人还有其他的行为,为何使用Replace Delegation with Inheritance(以继承取代委托)
把它变成实责对象的子类呢。这样就既可以扩展元对象的行为,又不必负担那么多的委托动作。
4 狎昵关系(Inappropriate Intimacy)
若果两个类花太多时间去太久彼此的private成分,就说明有这种坏味道。
为了拆解这种关系,可以使用Move Method(搬移函数)
和Move Field(搬移字段)
帮他们划清界限,减少这种关联关系。
也可以看看是否可以运用Change Bidirectional Association to Unidirectional(将双向关联改为单向关联)
让其中一个类对另一个斩断情丝。
如果无法拆解,则可以吧两者共同点提炼到一个安全地点,让他们使用这个新类。也可以尝试使用Hide Delegate(隐藏委托关系)
让另一个类来传递这种关联关系。
继承往往会造成过度亲密,子类对超类的了解总是超过超类的主观愿望,如果有必要,可以运用Replace Inheritance with Delegation(以委托取代继承)
让子类离开继承体系。