代理模式(Proxy Pattern)
为其他对象提供一种代理以控制对这个对象的访问。
在某些情况下,客户不想或者不能直接引用一个对象,这个时候就用到了代理类,代理对象可以在客户和目标对象之间起到中介的作用,客户端分辨不出代理对象与真实对象的区别。
Proxy模式的要点:
1、“增加一层间接层”是软件系统中对许多负责问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
2、具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象作细粒度的控制,有些可能对组件模块提供抽象代理层,在架构层次对对象作proxy。
3、proxy并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。
不同类型的代理模式:
1、远程代理
可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担了大部分的网络通信工作。
2、虚拟代理
使用虚拟代理模式的优点就是代理对象可以在必要的时候才将被代理的对象加载。代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的时候,虚拟代理的优点就非常明显。
3、保护代理
保护代理可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。
4、智能引用代理
在访问一个对象时可以执行一些内务处理(Housekeeping)操作,比如计数操作等。
接口类:
public interface ISubject {
public void method();
}
被代理类:
public class RealSubject implements ISubject {
public void method() {
System.out.println("\t调用RealSubject类的method方法!");
}
}
代理类:
public class SubjectProxy implements ISubject {
private ISubject subject;
public SubjectProxy(ISubject subject){
this.subject = subject;
}
public void method() {
System.out.println("SubjectProxy.method start");
subject.method();
System.out.println("SubjectProxy.method end");
}
}
代理类的另一种写法(虚拟代理类):
public class SubjectProxy implements ISubject {
private ISubject subject;
public void setSubject(ISubject subject){
this.subject = subject;
}
public void method() {
//在第一次访问时才创建对象
if(subject==null){
subject = new RealSubject();
}
System.out.println("SubjectProxy.method start");
subject.method();
System.out.println("SubjectProxy.method end");
}
}
测试类:
public class SubjectTest {
public static void main(String[] args) {
ISubject subject = new RealSubject();
ISubject proxy = new SubjectProxy(subject);
proxy.method();
}
}
输出结果:
SubjectProxy.method start
调用RealSubject类的method方法!
SubjectProxy.method end