Replace Delegation with Inheritance (以继承取代委托)

Summary:你在两个类之间使用委托关系,并常常为整个接口编写许多极简单的委托函数。让委托类继承受托类java

                                               

动机函数

本重构与Replace Inheritance with Delegation 偏偏相反。若是你发现本身须要使用受托类中的全部函数,而且费了很大力气编写全部极简的委托函数,本重构能够帮助你轻松回头使用继承。测试

两条告诫需牢记于心。首先,若是你并无使用受托类的全部函数,那么就不该该使用Replace Delegation With Inheritance,由于子类应该老是遵循超类的接口。若是过多的委托函数让你烦心,你有别的选择:你能够经过Remove Middle Man 让客户端本身调用受托看书,也可使用Extract Superclass 将两个类接口相同的部分提炼到超类中,而后让两个类都继承这个新的超类;你还能够用相似的手法使用Extract Interfacespa

另外一种须要小心的状况是:受托对象被不止一个其余对象共享,并且受托对象是可变的。在这种状况下,你就不能将委托关系替换为继承关系,由于这样就没法再共享数据了。共享数据是必须由委托关系承担的一种责任,你没法把它转给继承关系。若是受托对象是不可变的,数据共享就不成问题,由于你大可放心地复制对象,谁都不会知道设计

作法code

   1.让委托端成为受托端的一个子类对象

   2. 编译。继承

注意:此时某些函数可能会发生冲突:它们可能有相同的名称,但在返回类型、异常指定或可见程度方面有所差别。你可使用Rename Method解决此类问题。递归

3.将受托字段设为该字段所处对象自己。接口

4.去掉简单的委托函数。

5.编译并测试。

6.将全部其余设计委托关系的代码,改成调用对象自身。

7.移除受托字段

范例:

下面是一个简单的Employee类,将一些函数委托给另外一个一样简单的Person类:

class Employee{
    Person _person = new Person();
    public String getName(){
        return _person.getName();
    }
    
    public void seName(String arg){
        _person.setName(arg);
    }
    
    public String toString(){
        return "Emp:" + _person.getLastName();
    }
}

class Person(){
    String _name;
    public String getName(){
        return _name;
    }
    
    public void setName(String arg){
         _name = arg;
     }
     
     public String getLastName(){
              return _name.subString(_name.lastIndexOf(' ') + 1);
     }
}

第一步,只需声明二者之间的继承关系:

class Employee extends Person

此时,若是有任何函数发生冲突,编译器会提醒咱们。若是某几个函数的名称相同,但返回类型不一样或抛出不一样的异常,它们之间就会出现冲突。全部此类问题均可以经过Rename Method加以解决。为求简化,范例中哦没有列出这些麻烦的状况。

下一步要将受托字段设值为该字段所处对象自身。同时,必须先删掉全部简单的委托函数(例如getName()和setName())。若是刘翔这种函数,就会由于无限递归而引发系统调用栈溢出。在此范例中,咱们应该把Employee的getName()和setName()拿掉。

一旦Employee能够正常工做了,就修改其中用到委托函数的代码,让它们直接调用从超类继承而来的函数:

public String toString(){
    return "Emp: " + getLastName();
}

摆脱全部涉及委托关系的函数后,也就能够摆脱_person这个受托字段了。

相关文章
相关标签/搜索