代理模式是GoF23种Java常用设计模式之一,采用了对象的结构模式,能够为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一 个客户不想直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
代理模式的特征
代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的 对象的相关方法,来提供特定的服务。
代理模式涉及到的角色
代理模式一般涉及到三个角色:实例
以《Java与模式》中的示例为例
//抽象角色 public abstract class Subject { abstract public void request(); }
//真实角色 public class RealSubject extends Subject { public RealSubject() { super(); } @Override public void request() { System.out.println("From real subject."); } }
//代理角色 public class ProxySubject extends Subject { private RealSubject realSubject; // 以真实角色作为代理角色的属性 public ProxySubject() { } public void request() { // 该方法封装了真实对象的request方法 preRequest(); if (realSubject == null) { realSubject = new RealSubject(); } realSubject.request(); // 此处执行真实对象的request方法 postRequest(); } private void preRequest() { // something you want to do before requesting } private void postRequest() { // something you want to do after requesting } }
//Test public class TestProxy { public static void main(String[] args) { Subject sub = new ProxySubject(); sub.request(); } }
从上面的代码我们可以看出,客户实际调用的是RealSubject类的request()方法,现在用ProxySubject来代理RealSubject类,同样达到目的,同时还封装了其他方法(preRequest(),postRequest()),可以处理一些其他问题。
上面代码实现的代理模式中,真实角色是事先已经定义好的,并将其作为代理对象的内部属性,这种代理模式称之为静态代理。而实际使用中,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这就是我们后面要探讨的动态代理了。
使用场景
代理模式使用场景非常多,如面向切面编程(Spring中的AOP),虚代理模式(hibernate中的懒加载),保护代理(权限服务控制),远程代理(Java中的RMI技术)等。
常见的代理有哪些二、按照代理用途来分类
(1)远程代理(Remote Proxy) -可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。