意图:
为其他对象提供一种代理,以控制对这个对象的访问;
动机:
对一个对象进行访问控制的一个原因是为了自由我们确定需要这个对象时才对它进行创建和初始化;
对于每一个开销很大的对象,应该根据需要进行创建;
适用性:
在需要用比较通用和复杂的对象指针替代简单的指针的时候,使用 Proxy 模式;
参与者:
Proxy
保存一个引用使得代理可以访问实体;
提供一个与 Subject 和接口相同的接口,这样代理就可以用来替代实体;
控制对实体的存取,并可能负责创建和删除它;
Subject
定义 RealSubject 和 Proxy 的共同接口,这样就在任何使用 RealSubject 的地方都可以使用 Proxy.
RealSubject
定义 Proxy 所代表的实体;
/**
* 抽象主题
* @author Administrator
*
*/
public interface Subject {
// 定义一个方法
public void request();
}
/**
* 真实主题类
* @author Administrator
*
*/
public class RealSubject implements Subject {
// 实现方法
@Override
public void request() {
// 业务逻辑处理
}
}
/**
* 代理类
* @author Administrator
*
*/
public class Proxy implements Subject{
// 要代理哪个实现类
private Subject subject = null;
// 默认被代理者
public Proxy(){
this.subject = new Proxy();
}
// 通过构造函数传递代理者
public Proxy(Object ...objects ){
}
// 实现接口中定义的方法
@Override
public void request() {
// TODO Auto-generated method stub
}
}
动态代理
动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定哪一个对象。
动态代理实现代理的职责,业务逻辑 Subject 实现相关的逻辑功能,两者之间没有必然的相互耦合关系。
/**
* 抽象主题
* @author Administrator
*
*/
public interface Subject {
// 定义一个方法
public void request();
}
/**
* 真实主题类
* @author Administrator
*
*/
public class RealSubject implements Subject {
// 实现方法
@Override
public void request() {
// 业务逻辑处理
}
}
/**
* 动态代理的 Handler 类
* @author Administrator
*
*/
public class MyInvocationHandler implements InvocationHandler{
// 被代理的对象
private Object targert = null;
public MyInvocationHandler(Object _obj){
this.targert = _obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 执行被代理的方法
return method.invoke(this.targert, args);
}
}
/**
* 动态代理类
* @author Administrator
*
*/
public class DynamicProxy<T> {
public static <T> T newProxyInstance(ClassLoader loader, Class<?>[]
interfaces, InvocationHandler h){
// 执行目标,并放回结果
return (T) Proxy.newProxyInstance(loader, interfaces, h);
}
}
/**
* 动态代理的场景类
* @author Administrator
*
*/
public class Client {
public static void main(String[] args) {
// 定义一个主题
Subject subject = new RealSubject();
// 定义一个 Handler
InvocationHandler handler = new MyInvocationHandler(subject);
// 定义主题的代理
Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(),
subject.getClass().getInterfaces(), handler);
// 代理的行为
proxy.request();
}
}
内容摘自
《设计模式 可复用面向对象软件的基础》
《设计模式之禅》