静态代理通常用于对原有业务逻辑的扩充。比如你有一个已实现的功能类,并且调用了其中的某些方法。由于需求变更,你需要加入日志打印,但又不合适将逻辑 直接加入其中。所以可以创建一个代理类来实现。
实现步骤:
- 创建代理类,实现和待扩展功能类一样的方法。
- 通过代理类持有真实对象
- 然后在源代码中调用代理类方法,来添加我们新加入的业务逻辑
一个典型的代理模式通常有三个角色:
- Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
- RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。
- Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。
共同接口
public interface Action {
public void doSomething();
}
真实对象
public class RealObject implements Action{
public void doSomething() {
System.out.println("do something");
}
}
代理对象
public class Proxy implements Action {
private Action realObject;
public Proxy(Action realObject) {
this.realObject = realObject;
}
public void doSomething() {
System.out.println("proxy do");
realObject.doSomething();
}
}
运行代码
Proxy proxy = new Proxy(new RealObject());
proxy.doSomething();
实现原理
优缺点
优点:不破坏原代码,不影响原来老的功能
缺点:如果有10个这样的功能类RealObject
,而且我们要去代理的方法是不同的,比如代理:doSomething、doAnotherThing、doTwoAnotherThing等方法
realObject.doSomething();
realObject1.doAnotherThing();
realObject2.doTwoAnother();
缺点解决方案
为这些方法创建不同的代理类,使用不同的代理对象独自完成,代理后的代码如下
//不同的代理对象,独自完成 proxy.doSomething(); proxy1.doAnotherThing(); proxy2.doTwoAnother();
创建一个综合型的Proxy,实现Action1、Action2、Action3.....,并且持有不同的realObject实例,由一个proxy代理对象来调用其他方法,但这样会显得非常膨胀,非常臃肿
//同一个代理对象,持有不同的realObject实例 proxy.doSomething(); proxy.doAnotherThing(); proxy.doTwoAnother();
你的类结构就变成了如下样子
这种综合型的操作,非常难以维护,若出现方法名相同,仅参数不同的对象,调用的时候需要额外判断,否则容易出错