一、静态代理实现
按照代理模式的类图:
静态代理,代理类在编译时生成;即,需要编码代理类。
从实现上来看,静态代理类不具备真实主题类处理真正请求的能力,因此需要将请求交给真实主题对象处理;为了获取真是主题类的能力,代理类可以继承真实主题类,或者组合真实主题对象。
设计原则
多用组合,少用继承
即使通过继承可以满足需求,但是由于继承不如组合灵活,采用组合会更好一些。
由此,静态代理的实现步骤一般为(主题接口Subject, 真实主题对象类RealSubject一般都是存在的):
- 创建代理类,实现主题接口Subject;
- 代理类持有真实主题对象类的引用;
- 代理类实现主题接口Subject的方法,并委托给引用的真实主题对象类处理。
二、实例:计算耗时操作
要为一项耗时操作计时,最直观的做法是在耗时操作前后打印当前时间,但是这样的代码不利于维护。使用代理模式,从设计上
- 首先需要为计时操作创建接口,即主题接口
- 实现主题接口,即真实主题类提供真正的耗时操作
- 代理类组合真是主题类实例,实现主题接口
- 客户端使用代理类完成耗时任务请求
实现类图如下
完整代码见附录。
refer to
[1] java静态代理和动态代理
附录
静态代理实现
// Subject主题接口
public interface Subject {
void doTask();
}
// 真是主题类,真正处理请求的类
public class RealSubject implements Subject {
@Override
public void doTask() {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 拦截对真实主题对象访问,代理类
public class Proxy implements Subject {
private Subject realSubject;
public Proxy(Subject realSubject) {
this.realSubject = realSubject;
}
@Override
public void doTask() {
long start = System.currentTimeMillis();
System.out.println("task begins");
realSubject.doTask();
System.out.println("task ends, duration: \t" + (-start + System.currentTimeMillis()) / 1000 + "s");
}
}
// 客户端代理
public class Client {
public static void main(String[] args) {
Subject realSubject = new RealSubject();
Subject proxy = new Proxy(realSubject);
proxy.doTask();
}
}