重构类关系-Replace Delegation with Inheritance以继承取代委托十二

重构类关系-Replace Delegation with Inheritance以继承取代委托十二

1.以继承取代委托

1.1.使用场景

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

本重构与Replace Inheritance with Delegation (352)恰恰相反。如果你发现自己需要使用受托类中的所有函数,并且费了很大力气编写所有极简的委托函数,本重构可以帮助你轻松回头使用继承。

两条告诫需牢记于心。首先,如果你并没有使用受托类的所有函数,那么就不应该使用Replace Delegation With Inheritance (355),因为子类应该总是遵循超类的接口。如果过多的委托函数让你烦心,你有别的选择:你可以通过Remove Middle Man (160)让客户端自己调用受托函数,也可以使用Extract Superclass (336)将两个类接口相同的部分提炼到超类中,然后让两个类都继承这个新的超类;你还可以用类似的手法使用Extract Interface (341)。”

另一种需要当心的情况是:受托对象被不止一个其他对象共享,而且受托对象是可变的。在这种情况下,你就不能将委托关系替换为继承关系,因为这样就无法再共享数据了。数据共享是必须由委托关系承担的一种责任,你无法把它转给继承关系。如果受托对象是不可变的,数据共享就不成问题,因为你大可放心地复制对象,谁都不会知道。

1.2.如何做

  • 让委托端成为受托端的一个子类。
  • 编译。
  • 此时,某些函数可能会发生冲突:它们可能有相同的名称,但在返回类型、异常指定或可见程度方面有所差异。你可以使用Remane Method (273)解决此类问题。
  • 将受托字段设为该字段所处对象本身。
  • 去掉简单的委托函数。
  • 编译并测试。
  • 将所有其他涉及委托关系的代码,改为调用对象自身。
  • 移除受托字段。

1.3.示例

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

class Employee {
    
    
  Person _person = new Person();
  public String getName() {
    
    
      return _person.getName();
  }
  public void setName(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 (273)加以解决。为求简化,我没有在范例中列出这些麻烦情况。”
“下一步要将受托字段设值为该字段所处对象自身。同时,我必须先删掉所有简单的委托函数(例如getName()和setName())。如果留下这种函数,就会因为无限递归而引起系统调用栈溢出。在此范例中,我应该把Employee的getName()和setName()拿掉。
一旦Employee可以正常工作了,我就修改其中用到委托函数的代码,让它们直接调用从超类继承而来的函数:

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

摆脱所有涉及委托关系的函数后,我也就可以摆脱_person这个受托字段了。

猜你喜欢

转载自blog.csdn.net/m0_38039437/article/details/129790142