《重构》读书笔记

《重构》学习笔记(05)-- 在对象之间搬移特性

2019-06-09  本文已影响0人  若隐爱读书

在对象设计的过程中,“决定把责任放在哪儿”是最重要的事情之一。但无论使用对象技术多么娴熟,也无法保证在设计对象时一次做对。因此,需要进行重构,改变原有的设计。

Move Method(搬移函数)

简单的说就是将一个类中的函数搬移到另一个类中。


image

重构后


image
这种重构方式看似简单,其中的难点在于确定是否应该移动一个函数。通常,我们的做法如下:

Move Field(搬移字段)

Move Field与Move Method类似,将一个字段搬移到更适合的类中。


image

重构后


image
随着系统的发展,你会发现你需要新的类,并将现有的工作责任拖到新类中。通常我们的做法为:

Extract Class(提炼类)

如果某个类做了应该由两个类做的事。那么建立一个新类,将相关的字段和函数从旧类搬移到新类。


image

重构后


image
一个类应该是一个清楚的抽象,处理一些明确的责任。有些类含有大量的函数和数据,这样的类往往太大而不易理解,此时需要考虑哪些部分可以分离出去,并将它们分离到一个单独的类中。如果子类化只影响类的部分特性,或某些特性需要以一种方式来子类化,某些特性则需要以另一种方式子类化,这就意味需要分解原来的类。做法:

Inline Class(将类内联化)

如果某个类没有做太多事情,可以将这个类中所有的特性搬移到另一个类中,然后移除原类。


image

重构后


image
做法:

Hide Delegate(隐藏“委托关系”)

客户类通过一个委托类调用另一个对象,在服务类上建立客户所需的所有函数,用以隐藏委托关系。


image

重构为
[图片上传失败...(image-b9ec27-1560092577298)]
做法为:

Remove Middle Man(移除中间人)

移除中间人与Hide Delegate是逆操作。如果某个类做了过多的简单委托动作,那么让客户直接调用受委托类。


image

重构为


image
委托的代价是,委托对象的变化会引起服务器对象变化。当服务类完成成了委托类的中间人,那么请删除中间人吧!不断使用Hide Delegate和Move Middle Man调整程序结构。做法为:

Introduce Foreign Method(引入外加函数)

如果你正在使用一个类,但是你需要一项新的服务,这个类却无法修改或无法供应。此时你应该在客户类中新建一个函数,并以第一参数形式传入一个服务类的实例。
例如,我们需要获取一个Date的下一天。

Date newStart = new Date(previousEnd.getYear(),
                     previousEnd.getMonth(),previousEnd.getDate()+1);

可以重构为:

Date newStart = nextDay(previousEnd);
private static Date nextDay(Date arg){
    return new Date(arg.getYear(), arg.getMonth(),arg.getDate()+1);
}

在进行本项重构时, 如果你以外加函数实现一项功能, 那就是一个明确信号: 这个函数原本应该在提供服务的类中实现.但是不要忘记: 外加函数终归是权宜之计. 如果不能把外加函数搬移到服务类中, 就把外加函数交给服务类的持有者, 请他帮你在服务类中实现这个函数.本项重构一般的做法为:

Introduce Local Extension(引入本地扩展)

如果你需要为服务类提供一些额外函数,但你无法修改这个类。那么建立一个新的类,使它包含这些额外函数,让这个扩展品成为源类的子类或者包装类。


image

重构为


image
例如以Date类为例,如果我们需要扩展,我们可以使用子类:
class MfDateSub extends Date{
    public MfDateSub nextDay()...
    public int dayOfYear()...
}

或者使用扩展类

class MfDateWrap{
    private Date _original;
}

常用的做法:

上一篇 下一篇

猜你喜欢

热点阅读