代理模式

代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问。

现实生活中就有很多代理模式的影子:假设你是一个公司的工程师,能提供一些技术服务,还有一个公司的客服,他不懂技术,而我是公司的客户,需要你们公司提供技术服务。显然,我不会直接去找你,我只会去和客服沟通。这是客服会根据情况来决定找不找你提供技术服务,当然客服也可以提供一些额外的服务。对我而言,我根本不需要接触到你,只需要与客服沟通就行了。事实上,站在我的角度,客服就代表了你们公司,不需要去了解真正为我服务的是谁。

代理模式示意图:

场景

一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,解除调用者和真实对象之间的耦合。

代理模式体现在编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。

代理模式结构

  • 抽象角色(Subject):通过接口或抽象类声明真实角色实现的业务方法。

  • 真实角色(RealSubject):实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

  • 代理角色(Proxy):实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

代理模式类图:

进一步了解代理模式

优点:

  • 代理对象可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能,符合开闭原则

  • 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。

缺点:

  • 在客户端和目标对象增加了一个代理对象,会造成请求速度变慢

  • 增加系统的复杂性。

代理模式分类

  1. 静态代理:静态定义代理类,我们自己静态定义的代理类。

  2. 动态代理:通过程序动态生成代理类,该代理类不是我们自己定义的,而是由程序自动生成,常用的动态代理技术有JDK自带的动态代理和CGLIB动态代理。

代码实例

这里,先介绍静态代理的代码实例,关于动态代理的JDK实现以及用CGLIB包的实现会在后面的博客中详细学习。

代码演示内容:明星与其经纪人的工作模式

抽象角色(Subject):

1
2
3
4
5
6
public interface Star {
void signContract();//签合同
void sing();//演出
void collectMoney();//收尾款
}

真实角色(RealSubject):明星本人

1
2
3
4
5
6
7
8
9
10
11
12
13
public class RealStar implements Star{
@Override
public void signContract() {
}
@Override
public void sing() {
System.out.println("演出");//真实角色的操作:真正的业务逻辑
}
@Override
public void collectMoney() {
}
}

代理角色(Proxy):明星的经纪人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ProxyStar implements Star{
private Star star;//真实对象的引用(明星)
@Override
public void signContract() {
System.out.println("ProxyStar.signContract()");
}
@Override
public void sing() {
star.sing();//真实对象的操作(明星唱歌)
}
@Override
public void collectMoney() {
System.out.println("ProxyStar.collectMoney()");
}
public ProxyStar(Star star) {//通过构造器给真实角色赋值
this.star = star;
}
}

测试:

1
2
3
4
5
6
7
8
public static void main(String[] args) {
Star real = new RealStar();
Star proxy = new ProxyStar(real);
proxy.signContract();//代理完成
proxy.sing();//真实对象的操作(明星唱歌)
proxy.collectMoney();//代理完成
}

我们通过这个例子,可以看出来静态代理是手动创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

上述例子中,只有唱歌这个方法是明星本人来完成的,其他的方法例如签合同和收钱等都是由代理(经纪人)来完成,明星与经纪人就是现实生活中典型的代理模式的例子。

关于代理模式,应用最多的还是动态代理。动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。在后续博客中,会详细介绍动态代理。

0%