代理模式 gaunthan Posted on Feb 7 2017 ? Design Patterns ? > **代理模式**(Proxy Pattern)为另一个对象提供一个替身或占位符以控制对这个对象的访问。 <!--more--> ## 概述 代理可以用于控制和管理访问,它的形式有许多种。在真实的世界中,代理模式有许多变体,这些变体都有共同点:都会将客户对主题(Subject)施加的方法调用拦截下来。这种间接的级别让我们可以做许多事情,包括: - 将请求分发到远程主题; - 给创建开销大的对象提供代表; - 提供某些级别的保护,这种保护决客户能够调用的方法。 其实一般的代理模式还可以以许多形式使用。 代理控制访问的方式有以下几种: - 远程代理控制访问远程对象。 - 虚拟代理控制访问开销大的资源。 - 保护代理基于权限控制对资源的访问。 ## 结构 代理模式的类图如下所示:  结构说明如下: 组成成分|说明 --|-- Subject|Proxy和RealSubject都需要实现的接口,从而允许任何客户都可以像处理RealSubject对象一样地处理Proxy对象。 Proxy|Proxy持有RealSubject的引用,所以必要时它可以将请求转发给RealSubject。 RealSubject|通常是真正做事的对象,它是被Proxy代理和控制访问的对象。 ## 常见用途 ### 远程代理 **远程代理**(Remote Proxy)可以作为另一个JVM上对象的本地代表。调用代理的方法,会被代理利用网络转发到远程执行,并且结果会通过网络返回给代理,再由代理将结果转给客户:  图片来源:[[Android] 代理模式](http://blog.qiji.tech/archives/8284)。 ### 虚拟代理 **虚拟代理**(Virtual Proxy)作为创建开销大的对象的代表。虚拟代理经常直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象:  考虑一个从音乐网站加载CD封面的应用程序。由于连接带宽和网络负载,下载封面需要一定时间,所以希望在加载图像的时候,能够默认显示一些东西。同时,希望在等待图像加载时应用程序不被挂起。一旦图像被加载完成,默认显示的东西应该消失,并把CD封面显示出来。 想完成这个目的,简单的方式就是利用虚拟代理。虚拟代理可以代理特定的图像接口,如Java Swing中的Icon,管理背景的加载,并在加载未完成时显示“CD封面加载中,请稍后……”。一旦加载完成,代理就把显示的职责委托给Icon:  ### 保护代理 **保护代理**(Protext Proxy)基于调用者控制对对象方法的访问。不同的保护代理类代表了不同的权限域,客户在这些域上只能使用特许的操作。 ## 其他用途 ### 防火墙代理 **防火墙代理**(Firewall Proxy)控制资源的访问,保护主题免于恶意客户的侵害。常用于防火墙系统。 ### 智能引用代理 **智能引用代理**(Smart Reference Proxy)在主题被引用时进行额外的动作,如计算一个对象被引用的次数。常用于审计系统。 ### 缓存代理 **缓存代理**(Caching Proxy)为开销大的运算结果提供暂时存储,它也允许多个客户共享结果,以减少计算或网络延迟。常用于Web服务器代理,以及内容管理与出版系统。 ### 同步代理 **同步代理**(Synchronization Proxy)在多线程的情况下为主题提供安全的访问。常用于为分布式环境内的潜在对象集合提供同步访问控制。 ### 复杂隐藏代理 **复杂隐藏代理**(Complexity Hiding Proxy)用来隐藏一个类的复杂集合的复杂度,并进行访问控制。有时候也称为**外观代理**(Facade Proxy)。 复杂隐藏代理和[外观模式](http://gaunthan.leanote.com/post/%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F)是不一样的,因为代理控制访问,而外观模式只提供一组接口。 ### 写时复制代理 **写时复制代理**(Copy-On-Write Proxy)用来控制对象的复制,方法是延迟对象的复制,直到客户真的需要为止。这是虚拟代理的变体。 ## References - 弗里曼弗里曼谢拉贝茨 O'ReillyTaiwan 公司 UMLChina. Head First 设计模式 [M]. 中国电力出版社, 2007. 赏 Wechat Pay Alipay Transport-layer Protocols 状态模式