假设一个系统已经有一个对象A,现在需要向这个系统加入一个新的对象C。对象C需要使用系统中已有的对象A,但是C不能像系统一在使用A这样使用A,要么是A提供的接口不符合C的要求,要么是A的功能需要进一步加强等。
这时候可以选择修改对象A,也可以选择使用一个中介对象B,让对象B将调用传递给对象A。这样新的对象C使不必直接与系统中已有对象A打交道,而是通过对象B与A打交道;而对象B则可以利用这一有利位置为对象C提供一个与A完全不同的接口,或者做一些A 本来不做的操作,比如将客户端的请求计数等。B就是一个代理。
代理模式下,一共有这样几种角色:
抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方也可以使用代理主题。
真实主题角色(RealSubject):真正的主题对象。
代理主题角色(ProxySubject):代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候替代真实主题;控制对真实主题的引用,负责在需要的时候创建(以及删除)真实主题对象;代理角色通常在将客户端调用传递给真实的主题对象之前或之后,都要执行某个操作,而不是单纯地将调用传递增给真实主题对象。
以下是示例代码:
package
proxy;
public interface Subject ... {
public void request();
}
package proxy;
public class RealSubject implements Subject ... {
public void request() ...{
System.out.println(this + ".request()");
}
}
package proxy;
public class ProxySubject implements Subject ... {
private RealSubject real;
public void request() ...{
preRequest();
if (real == null)
real = new RealSubject();
real.request();
postRequest();
}
public void preRequest() ...{
System.out.println(this + ".preRequest()");
}
public void postRequest() ...{
System.out.println(this + ".postRequest()");
}
public static void main(String [] args) ...{
Subject sub = new ProxySubject();
sub.request();
}
}
public interface Subject ... {
public void request();
}
package proxy;
public class RealSubject implements Subject ... {
public void request() ...{
System.out.println(this + ".request()");
}
}
package proxy;
public class ProxySubject implements Subject ... {
private RealSubject real;
public void request() ...{
preRequest();
if (real == null)
real = new RealSubject();
real.request();
postRequest();
}
public void preRequest() ...{
System.out.println(this + ".preRequest()");
}
public void postRequest() ...{
System.out.println(this + ".postRequest()");
}
public static void main(String [] args) ...{
Subject sub = new ProxySubject();
sub.request();
}
}
运行结果:
proxy.ProxySubject@7ced01.preRequest()
proxy.RealSubject@765291.request()
proxy.ProxySubject@7ced01.postRequest()