设计模式--代理模式

110 阅读3分钟

一 简介

代理模式(Proxy pattern):属于结构型设计模式,为另一个对象提供一个替身或占位符以控制对这个对象的访问。

二 意图

代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。

三 结构

image.png

  • Subject: 抽象主题角色 定义了被代理角色和代理角色的共同接口或者抽象类
  • RealSubject: 被代理角色 实现或者继承抽象主题角色,定义实现具体业务逻辑的实现
  • Proxy: 代理角色 实现或者继承抽象主题角色,持有被代理角色的引用,控制和限制被代理角色的实现,并且拥有自己的处理方法(预处理和善后)

四 代码实现

以下用娱乐圈中明星与经纪人的关系来更具体地解释代理模式。

经纪人的角色就相当于一个代理,要找到明星必须得先经过他的经纪人,经纪人负责给明星接洽各种商业活动,而明星只需要专注于拍电影、唱歌就好了。这就是为什么要用到代理的原因,抛开其他繁琐的事务,专注被代理人的业务逻辑,减轻被代理人的负担。

抽象主题角色: Subject

public interface Subject {
    public void filming ();
}

被代理角色: RealSubject

public class Star implements Subject {
    @Override 
    public void filming() { 
        System.out.println(getClass().getSimpleName() + ":经纪人接了一部电影,我主演");
    } 
}

代理角色:Proxy

public class Agent implements Subject {
    private Subject star;

    public Agent(Subject star) {
        this.star = star;
    }

    @Override
    public void filming() {
        System.out.println(getClass().getSimpleName() + ":剧本很好,这部电影接下了");
        star.filming();
    }
}

客户类调用:

public class Client {
    public static void main(String[] args) {
        Subject star = new Star();
        Subject proxy = new Agent(star);
        proxy.filming();
    }
}

表面上是调用了代理的方法,实际的执行者其实是被代理角色 Star:

Agent:剧本很好,这部电影接下了

Star:经经纪人接了一部电影,我主演

五 总结

优点:

  • 良好的扩展性。修改被代理角色并不影响调用者使用代理,对于调用者,被代理角色是透明的。
  • 降低耦合度。代理角色协调调用者和被代理角色,被代理角色只需实现本身关心的业务,非自己本职的业务通过代理处理和隔离。

缺点:

  • 增加了代理类,实现需要经过代理,因此请求速度会变慢。

使用场景:

  • 延迟初始化(虚拟代理): 如果有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式。
  • 访问控制(保护代理): 如果只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序(包括恶意程序),此时可使用代理模式。
  • 本地执行远程服务(远程代理): 适用于服务对象位于远程服务器上的情形。
  • 记录日志请求(日志记录代理): 适用于当需要保存对于服务对象的请求历史记录时。
  • 缓存请求结果(缓存代理): 适用于需要缓存客户请求结果并对缓存生命周期进行管理时, 特别是当返回结果的体积非常大时。
  • 智能引用: 可在没有客户端使用某个重量级对象时立即销毁该对象。