简单的了解下代理模式
代理就是一个人或一个机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或不能够直接引用对象,而代理对象可以在客户端和目标对象之间起到中介作用
代理模式包括远程代理,虚拟代理,copy-on-write代理,保护代理,catch代理,防火墙代理,同步化代理,只能引用代理,这些我就不一一介绍,我只是用简单例子,了解什么是代理模式。
代理模式设计到的角色:
抽象主题角色:声明了真是主题和代理主题的公共接口,这样可以使用真实主题的地方都可以使用代理主题。
代理主题角色:代理主题角色内不含有真实主题的引用,从而可以在任何时刻操作真实主题对象,代理主题角色提供一个与真实主题相同的接口,可以在任何时刻替代真实主题控制真实主题引用,负责在需要的时候创建真实主题对象(和删除真实主题对象),代理角色通常再将客户端调用传递给真实主题之前,或之后,都执行谋个操作,而不是单纯的将调用传递给真实主题。
真实主题角色:定义了代理角色所代表的真实对象
根据例子看看:
abstract public class Subject {
//定义抽象请求方法
abstract public void request();
}
真实主题
public class RealSubject extends Subject{
public RealSubject(){
}
public void request() {
// TODO Auto-generated method stub
System.out.println("请求");
}
}
代理主题
public class ProxySubject extends Subject{
private RealSubject realSubject;
public ProxySubject(){
System.out.println("进入代理类.......");
}
@Override
public void request() {
// TODO Auto-generated method stub
preRequest();
if(realSubject==null){
realSubject = new RealSubject();
}
realSubject.request();
postRequest();
}
/**
* 请求前操作
* */
private void preRequest(){
System.out.println("请求前");
}
/**
* 请求后操作
* */
private void postRequest(){
System.out.println("请求后");
}
}
测试代理
public class TestProxy {
public static void main(String[] args) {
Subject s = new ProxySubject();
s.request();
}
}
代理模式的时序图。
从这个测试不难看出代理类的作用,代理主题并不改变主题接口,模式的用意是不让客户端感觉到代理的存在,其次,代理使用委派将客户端的调用委派给真实主题对象,代理主题起到的是一个传递作用;最后,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯的传递请求。
接下来说说动态代理模式
public class VectorProxy implements InvocationHandler{
private Object proxyobj;
public VectorProxy(Object obj){
proxyobj = obj;
}
public static Object factory(Object obj){
Class cls = obj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new VectorProxy(obj));
}
/**
* 调用某个方法
* */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before calling"+method);
if(args!=null){
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
}
Object o = method.invoke(proxyobj, args);
System.out.println("after calling"+method);
return o;
}
public static void main(String[] args){
List<String> v = null;
v = (List) VectorProxy.factory(new Vector(10));
v.add("New");
v.add("York");
}
}
运行结果:
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
New
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
York
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
此例子用了反射,从结果可以看出代理对象截获了对Vector对象的所有调用,在调用传递给Vector之前和之后,代理对象具有采取合适操作的灵活性,虽然这里代理对象所采取的操作就是打印,也可以定义其他操作。