结构:
Subject是RealSubject和Proxy共同实现的接口。
RealSubject实现Subject接口,一般是实际的业务流程。
Proxy实现Subject接口,并且有一个指向RealSubject的引用,在Request方法实现中增加内容之后,调用RealSubject的Request方法。
定义:
为其他对象提供一种代理以控制对这个对象的访问【GOF】。
GOF的定义比较简洁,从实现的角度给出定义,结合上面的结构图,在client和RealSubject中间增加了一个中间对象,这个中间对象称
为Proxy,在Proxy对象里会有一个RealSubject的实例,Request方法会调用realSubject的Request方法。通过Proxy中间层来
控制对
RealSubject对象的访问。
软件系统中存在许多障碍,跨越这些障碍可能是复杂的。如果不小心,那么我们的软件就更多的在处理这些有关障碍的问题,
而不是本来要解决的问题。
上面的话摘自
《敏捷软件开发》,它从应用的角度解释了Proxy的内涵,RealSubject的Request等方法是真正的工作者,而Proxy的
Request方法中可以加入访问控制,网络环境处理,日志,执行时间计算等功能,这些就是所谓的障碍。
Proxy模式把实际的业务流程
和中间的环节解耦,把业务流程和障碍分离开来,这样系统更易于维护。
举例:
举一个最近在看得
spring技术手册的例子,作者提到了从一个Proxy例子开始介绍AOP。
一个业务流程在实现之后,想要在流程中增加日志功能,而且想达到动态增加的目的,如果不需要的话,可以随意移除日志功能。
UML图:
HelloProxy类中的hello方法增加了写日志操作。这个例子很简单,通过这个例子可以清楚的看到Proxy实现了业务和“障碍”的分离。接口定义:
public interface IHello {
public void hello();
}
接口实现:
public class HelloSpeaker implements IHello {
@Override
public void hello() {
// TODO Auto-generated method stub
System.out.println("Hello,Spring!");
}
}
代理实现:
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloProxy implements IHello {
private Logger logger = Logger.getLogger(this.getClass().getName());
@Override
public void hello() {
IHello helloImp = new HelloSpeaker();
// TODO Auto-generated method stub
log("begin hello...");
helloImp.hello();
log("end hello...");
}
private void log(String msg){
logger.log(Level.INFO, msg);
}
}
代理使用:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
IHello helloInstance = new HelloProxy();
helloInstance.hello();
}
}
输出结果:
2013-6-6 10:59:08 HelloProxy log
信息: begin hello...
Hello,Spring!2013-6-6 10:59:08 HelloProxy log
信息: end hello...