代理模式
简单讲:就是代理对象替代目标对象,通过代理对象访问目标对象,提供对目标对象的另一种访问模式。这里面含有一个编程思想:不要随意更改别人已经写好的代码,如果必须的话,就使用代理扩展之。
那么,我们如何使用代理模式呢?
我们先看一个类:
public class UserDao implements User{
public int num;
public void save(){
System.out.println("I can save.");
}
public int getNum() {
return num;
}
public void setNum(int a) {
this.num = a;
}
}
它的接口是:
public interface User {
public void save();
}
我们要做这个类的代理,对外提供save方法,该怎么做?
这样试试:
public class UserProxy implements User{
private User target;
public UserProxy(User target){
this.target = target;
}
public void save() {
target.save();
//代理对象在目标对象save方法的基础上,更改了目标对象save方法的输出
System.out.println("and I don't want to keep it any longer.");
}
public static void main(String[] args) {
UserDao u = new UserDao();
u.setNum(1);
UserProxy proxy = new UserProxy((User) u);
proxy.save();
}
}
嗯,可以对外提供save服务,而且也在UserDao代码不变的情况下,改变了原有的内容。可是还是缺了点什么,嗯,它太呆板了,只能代理User接口类,如果出现别的接口类就不行了。
该如何实现更灵活的实现呢?
首先,创建一个类,此类可以生成各种代理类;
其次,创建一个代理接口,声明一个方法,参数列表须有;
...
没错,java.lang.reflect包下有一个接口InvocationHandler,可以帮助我们实现更灵活的代理服务。
我们需要做的是,创建一个类,实现InvocationHandler接口,实现其invoke方法,声明扩展哪个方法,如何扩展。
测试时,实例化该类,然后使用Proxy类的newProxyInstance方法得到一个代理对象,调用其方法即可。