1. 委托机制
1.1 什么是委托机制?
A类持有B对象,外部程序调用A的某个方法,A再委托B去处理。
这种基于水平扩展A对象功能的方式,就称为java中的委托机制。
一般来讲,如何让A对象持有B对象的引用,存在两种常见方式:
- 通过外部注入的方式,即外部向A对象注入B对象。
- 通过内建的方式,即A对象自己完成B对象的实例化和初始化过程。
同样,B对象在A对象中以什么身份存在,也分为两种:
- B对象作为A对象的成员变量存在。
- B对象作为A对象的方法变量存在。
那实际上,上面组合下,即得出,让A对象持有B对象的引用,共有4种方式:
- A类中定义一个B类型的成员,以成员变量的方式接收B对象,外部向A类注入B对象,即以成员变量的方式注入B对象。
- A类中定义一个B类型的成员,以成员变量的方式接收B对象,A类自己实例化B对象,即以成员变量的方式内建B对象。
- A类中定义一个B类型的局部成员,以局部成员的方式接收B对象,在调用A类某个方法时,定义一个形式参数用来注入B对象,即以局部变量的方式注入B对象。
- A类中定义一个B类型的局部成员,以局部成员的方式接收B对象,在调用A类某个方法时,A类自己负责实例化B对象,即以局部变量的方式内建B对象。
tips:
委托机制的4种方式中,注入的方式用的比较多,内建的方式用的比较少。
因为注入的方式完全由程序外部进行控制,而内建的方式由成员内部直接固化,灵活度比较低,可扩展性不高。
并且作为成员变量被外部注入的方式尤其使用的最多,像spring中牛逼哄哄的依赖注入,实际上就是外部向目标bean注入成员变量。
在这里很有必要对外部注入成员变量的方式细分下,常见的具体注入成员变量的操作有两种:
- 外部直接通过构造方法向目标类注入成员变量,这要求目标类存在有参构造。
- 外部直接通过setter方法向目标类注入成员变量,这要求目标类存在setter方法。
2. 委托机制的实现方式
2.1 以成员变量的方式注入
ClassA:
package zeh.test.demo.com.call.back.weituo.waibu;
public class ClassA {
// 使用成员变量的方式接收外部的注入
private ClassB classB;
// 直接提供有参构造器的方式,暴露给客户端以便注入成员
public ClassA(ClassB classB) {
this.classB = classB;
}
// 也可以提供对应的setter方法,暴露给客户端以便注入成员,它和构造方法的方式二选一即可
public void setClassB(ClassB classB){
this.classB = classB;
}
public void testClassA() {
System.out.println("classA begin");
classB.testClassB();
System.out.println("classA end");
}
}
ClassB:
package zeh.test.demo.com.call.back.weituo.waibu;
public class ClassB {
public void testClassB() {
System.out.println("classB 提供的核心功能...");
}
}
TestWaiBu:
package zeh.test.demo.com.call.back.weituo.waibu;
public class TestWaiBu {
public static void main(String[] args) {
// 以成员变量的方式注入B对象
ClassB classB = new ClassB();
// 通过有参构造的方式注入外部成员classB
ClassA classA = new ClassA(classB);
classA.testClassA();
// 通过setter方法注入外部成员classB
classA = new ClassA(null);
classA.setClassB(classB);
classA.testClassA();
}
}
2.2 以成员变量的方式内建
ClassA:
package zeh.test.demo.com.call.back.weituo.neibu;
public class ClassA {
// 使用成员变量的方式,直接内建一个B对象
private ClassB classB = new ClassB();
public void testClassA() {
System.out.println("classA begin");
classB.testClassB();
System.out.println("classA end");
}
}
ClassB:
package zeh.test.demo.com.call.back.weituo.neibu;
public class ClassB {
public void testClassB() {
System.out.println("classB 提供的核心功能...");
}
}
TestNeiBu:
package zeh.test.demo.com.call.back.weituo.neibu;
public class TestNeiBu {
public static void main(String[] args) {
// 不用向A注入B对象,A内部已经内建了B对象
ClassA classA = new ClassA();
classA.testClassA();
}
}
2.3 以局部变量的方式注入
ClassA:
package zeh.test.demo.com.call.back.weituo.waibu;
public class ClassA {
// 定义局部变量 classB,用于接收外部的注入
public void testClassA(ClassB classB) {
System.out.println("classA begin");
classB.testClassB();
System.out.println("classA end");
}
}
ClassB:
package zeh.test.demo.com.call.back.weituo.waibu;
public class ClassB {
public void testClassB() {
System.out.println("classB 提供的核心功能...");
}
}
TestNeiBu:
package zeh.test.demo.com.call.back.weituo.waibu;
public class TestWaiBu {
public static void main(String[] args) {
// 以局部变量的方式注入B对象
ClassB classB = new ClassB();
ClassA classA = new ClassA();
classA.testClassA(classB);
}
}
2.4 以局部变量的方式内建
ClassA:
package zeh.test.demo.com.call.back.weituo.neibu;
public class ClassA {
public void testClassA() {
System.out.println("classA begin");
// 使用局部变量的方式,直接内建一个B对象
ClassB classB = new ClassB();
classB.testClassB();
System.out.println("classA end");
}
}
ClassB:
package zeh.test.demo.com.call.back.weituo.neibu;
public class ClassB {
public void testClassB() {
System.out.println("classB 提供的核心功能...");
}
}
TestNeiBu:
package zeh.test.demo.com.call.back.weituo.neibu;
public class TestNeiBu {
public static void main(String[] args) {
// 不用向A注入B对象,A内部已经内建了B对象
ClassA classA = new ClassA();
classA.testClassA();
}
}
3. 总结
委托机制是一种机制,是一种底层的思想。
很多设计模式或者设计理念都依赖委托机制,像方法转发、回调机制、钩子模式、代理设计模式、装饰者模式等,其底层都依赖的是委托机制。
委托机制的核心,实际上就是多态,说白了就是引用传递在多态中的应用,即向上转型。假如没有多态的话,则每个委托类只能委托一种类型的依赖对象,就失去了委托的核心功能。
文档信息
- 本文作者:Marshall