代码改变世界

结构模式 - 2 代理模式

2018-05-16 01:01  乱月灵猫  阅读(174)  评论(0编辑  收藏  举报
概述:
     假设一种场景,某个对象消耗太多资源,但我们的代码中并不是每个逻辑路径(if、else就是两条不同的逻辑路径)都需要这个对象,那么延迟加载可能是我们解决这个问题的一种方案。再假设一种场景,如果我们想限制访问某个对象,比如,提供一组方法给普通用户,提供另一组特别的方法给管理员用户。以上两个场景都比较相似,并且都需要解决一个更大的问题:如何提供一致的接口给某个对象,让它可以改变其内部的功能?解决方案是:可以通过引入一个新的对象A,来实现对真实对象B的操作,可以理解为将A作为B的替身,也就是代理对象。它可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户端不能看到的内容和服务,或者添加客户端需要的服务(AOP的思想)。
     怎样才能在不直接操作对象的情况下,对此对象进行访问?这个问题引出此篇要介绍的一种设计模式——代理模式。代理模式为不可访问的对象提供一种代理,以控制对这个对象的访问。对一个对象进行访问控制的原因是为了只有在我们确实需要这个对象的时候才对他进行创建和初始化。它是给某个对象提供一个代替者(占位者),使之在client对象和subject对象之间的编码更有效率。代理可以提供延迟实例化,控制访问等等功能。
 
四个作用:
    延迟加载
    类隐藏
    功能权限限制
    前后添加新功能
 
(1)当我们想要隐藏某个类时,可以为其提供代理类
(2)当一个类需要对不同的调用者提供不同的调用权限时,可以使用代理类来实现(代理类不一定只有一个,我们可以建立多个代理类来实现,也可以在一个代理类中金进行权限判断来进行不同权限的功能调用)
(3)当我们要扩展某个类的某个功能时,可以使用代理模式,在代理类中进行简单扩展(只针对简单扩展,可在引用委托类的语句之前与之后进行)     

应用场景:
     1) 远程代理(Remote Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
     2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
     3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
     4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
     5) Copy-on-Write代理:它是虚拟代理的一种,把复制操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。

结构:
 
可以看到,代理类和委托类都实现了接口

模式的组成元素:
     (1)Subject:抽象角色,它是真实角色和代理角色的共同接口,
     (2)RealSubject:真实角色,代理角色所代表的具体对象
     (3)Proxy:代理角色,保存一个实体的引用使得代理角色有权访问真实角色

效果:   
     Proxy模式在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途:
     (1)远程代理:可以隐藏一个对象存在于不同地址空间的事实,使得客户端可以访问在远程机器上的对象,远程机器可能有更好的计算性能与处理速度,可以快速响应并处理客户的请求
     (2)虚拟代理:可以进行最优化,例如根据要求创建对象,即通过使用一个小对象来代表一个大对象,可以减少系统资源消耗
     (3)保护代理和智能代理:都允许在访问一个对象时有一些附加的内务处理
     (4)copy on write:Proxy模式还可以对用户隐藏一种称之为写时复制的优化方式,大幅度降低拷贝庞大实体的开销,该优化与需要创建的对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果拷贝根本没有被修改,那么这些开销就没有必要。采用代理来延迟这一拷贝过程,我们可以保证只有当这个对象被修改时才对它进行拷贝。
     (5)缺点:实现代理模式需要额外工作,有时很复杂,而且增加了代理对象可能造成请求处理速度变慢