代理作为java中复用类的方式之一,虽然没有继承和组合使用的多,但也有其优点:
代理是继承与组合之间的中庸之道,不管是使用“组合”还是使用“继承”都会暴露成员对象/基类的所有方法,例如:
船需要一个控制模块:
构造船的一种方式是使用继承:public class ShipControls { public void forward(int velocity) {} public void back(int velocity) {} public void left(int velocity) {} public void right(int velocity) {} }
public class Ship extends ShipControls { private String name; public Ship(String name) { this.name = name; } public String toString() { return name; } public static void main(String[] args) { Ship zhengHeHao = new Ship("郑和号"); zhengHeHao.forward(100); } }
然而,Ship并非真正的ShipControls类型,即便你可以“告诉”Ship向前运动(forward())。更准确的讲,Ship包含ShipControls,与此同时,ShipControls的所有方法在Ship中都暴露了出来。代理解决了此难题:
public class ShipDelegation { private String name; private ShipControls controls; public ShipDelegation(String name) { this.name = name; } public void forward(int velocity) { controls.forward(velocity); } public void back(int velocity) { controls.forward(velocity); } public void left(int velocity) { controls.left(velocity); } public void right(int velocity) { controls.right(velocity); } }
可以看到,上面的方法是如何传递给了底层的controls对象,而其接口由此也就与使用继承得到的接口相同了。但是,我们使用代理时可以拥有更多的控制力,因为我们可以选择只提供在成员对象中的方法的某个子集。