美文网首页
设计模式之九——代理模式

设计模式之九——代理模式

作者: dd299 | 来源:发表于2019-06-28 18:28 被阅读0次

    原文传送门

    1 介绍

    代理模式是对象的结构模式。

    1.1 什么是代理模式

    代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

    1.2 解决了什么问题

    在某些情况下,一个客户不想或者不能直接引用一个对 象,此时可以通过一个称之为“代理”的第三者来实现 间接引用。代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务。

    通过引入一个新的对象(如小图片和远程代理 对象)来实现对真实对象的操作或者将新的对 象作为真实对象的一个替身,这种实现机制即 为代理模式,通过引入代理对象来间接访问一 个对象,这就是代理模式的模式动机。

    2 原理

    在代理模式中的角色:

    • Subject:抽象对象角色。声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
    • RealSubject:目标对象角色。定义了代理对象所代表的目标对象。
    • Proxy:代理对象角色。代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。

    2.1 uml图

    • 类图


      类图
    • 时序图


      时序图

    2.2 代码示例

    Subject代码示例

    public interface Subject {
        void request();
    }
    

    RealSubject代码示例

    public class RealSubject implements Subject {
        private static final String TAG = "RealSubject";
    
        @Override
        public void request() {
             System.out.println("  request:  ");
        }
    }
    

    Proxy代码示例

    public class Proxy implements Subject {
        private static final String TAG = "Proxy";
        private Subject realSubject;
    
        @Override
        public void request() {
            preRequest();
            if (realSubject == null) {
                realSubject = new RealSubject();
            }
            realSubject.request();
            afterRequest();
        }
    
    
    
        public void afterRequest() {
    
            System.out.println("request: postRequest");
        }
    
        public void preRequest(){
    
            System.out.println("request: preRequest");
        }
    }
    

    调用示例

    
        Subject subject = new Proxy();
        subject.request();
    
    

    运行结果

    request: preRequest
      request:  
    request: postRequest
    

    2.3 优缺点

    • 优点

      • 代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
      • 远程代理使得客户端可以访问在远程机器上的对象,远程机器 可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
      • 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
      • 保护代理可以控制对真实对象的使用权限。
    • 缺点

      • 由于在客户端和真实主题之间增加了代理对象,因此 有些类型的代理模式可能会造成请求的处理速度变慢。
      • 实现代理模式需要额外的工作,有些代理模式的实现 非常复杂。

    2.4 代理模式的常见类型

    根据代理模式的使用目的分类:

    • 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个本地 的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在 另一台主机中,远程代理又叫做大使(Ambassador)。
    • 虚拟(Virtual)代理:如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
    • Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟 到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个 开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
    • 保护(Protect or Access)代理:控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
    • 缓冲(Cache)代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
    • 防火墙(Firewall)代理:保护目标不让恶意用户接近。
    • 同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
    • 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,如将此对象被调用的次数记录下来等。

    3 适用场景

    3.1 常见应用

    EJB、Web Service等分布式技术都是代理模式的应用。在EJB中使用了RMI机制,远程服务器中的企业级Bean在本地有一个桩代理,客户端通过桩来调用远程对象中定义的方法,而无须直接与远程对象交互。在EJB的使用中需要提供一个公共的接口,客户端针对该接口进行编程,无须知道桩以及远程EJB的实现细节。

    3.2 动态代理

    动态代理是一种较为高级的代理模式,它的典型应用就是Spring AOP。
    在传统的代理模式中,客户端通过Proxy调用RealSubject类的request()方法,同时还在代理类中封装了其他方法(如preRequest()和postRequest()),可以处理一些其他问题。
    如果按照这种方法使用代理模式,那么真实主题角色必须是事先已经存在的,并将其作为代理对象的内部成员属性。如果一个真实主题角色必须对应一个代理主题角色,这将导致系统中的类个数急剧增加,因此需要想办法减少系统中类的个数,此外,如何在事先不知道真实主题角色的情况下使用代理主题角色,这都是动态代理需要解决的问题。
    动态代理的原理会另外单独讨论。

    4 与其他模式的关系

    代理模式与装饰者模式的区别

    • UML类图基本没区别,都是实现同一个接口,一个类包装另一个类。
    • 两者的定义:
      装饰器模式:能动态的新增或组合对象的行为
      在不改变接口的前提下,动态扩展对象的功能
      代理模式:为其他对象提供一种代理以控制对这个对象的访问
    • 在不改变接口的前提下,控制对象的访问
      装饰模式是“新增行为”,而代理模式是“控制访问”。关键就是我们如何判断是“新增行为”还是“控制访问”。你在一个地方写装饰,大家就知道这是在增加功能,你写代理,大 家就知道是在限制。

    5 总结

    代理模式就是给一个对象提供一个代理,并由代理对象控制对原对象的引用。它使得客户不能直接与真正的目标对象通信。代理对象是目标对象的代表,其他需要与这个目标对象打交道的操作都是和这个代理对象在交涉。
    代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的,同时也在一定程度上面减少了系统的耦合度。


    参考书籍及文章
    1.《Java与模式》,电子工业出版社,阎宏

    1. 《大话设计模式》,清华大学出版社,程杰
    2. 《设计模式——可复用面向对象软件的基础》,机械工业出版社,Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides
    3. 《Head First 设计模式(中文版)》,中国电力出版社
    4. 《图说设计模式》,https://design-patterns.readthedocs.io/zh_CN/latest/index.html
    5. 《设计模式总结》,https://www.cnblogs.com/chenssy/p/3357683.html

    相关文章

      网友评论

          本文标题:设计模式之九——代理模式

          本文链接:https://www.haomeiwen.com/subject/mcgecctx.html