代理模式(Proxy Pattern)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
描述:
让我们思考一下下面的代码:
//Client
1.class Customer{
2.public void someMethod(){
3.//Create the Service Provider Instance
4. FileUtil futilObj=new FileUtil();
5.//Access the Service
6.futilObj.writeToFile(“Some Data”);
7. }
8.}
作为它实现的一部分,Customer类创建了一个FileUtil类的一个实例并且直接访问它的服务。换句话说,对于客户对象,访问FileUtil对象的方式是很直接的。它的实现可能是客户对象访问服务提供者对象最为普通的方式了。相比较,有些时候客户对象可能不直接访问服务提供者(也就是指目标对象),这种情况是由于下面的原因导致的:
(1)目标对象的位置??目标对象可能存在于同一台或者不同机器的不同地址空间。
(2)目标对象的存在形式??目标对象可能直到他被请求服务的时候还不存在,或者对象被压缩。
(3)特殊的行为??目标对象可以根据客户对象的访问权限接受或拒绝服务。在多线程环境,一些服务提供者对象需要特殊的考虑。
在这些情况下,代理模式(Proxy Pattern)建议不要使有特殊需求的客户对象直接访问目标对象,而是使用一个单独的(分离的)对象(也就是指代理对象)为不同的客户提供通常的、直接的访问目标对象的方式。
代理对象提供和目标对象一样的接口。代理对象负责与目标对象交互的细节,代表客户对象与目标对象交互。所以客户对象不再需要处理访问目标对象的服务时的特殊需求。客户对象通过它的接口调用代理对象,代理对象直接把这些调用依次地传递给目标对象。客户对象不需要知道代理的原对象(目标对象)。代理对象隐藏了与客户对象进行交互的对象细节,如:对象是否是远程的、是否初始化、是否需要特殊的权限等。换句话说,代理对象作为客户和不可访问的远程对象或推迟初始化对象之间的透明桥梁。
代理对象因使用的场景不同,代理的种类也不同。让我们来快速的浏览一下一些代理和它们的目标。
注意:表23.1列出了不同种类的代理对象,在一章中,仅讨论远程代理,其他的一些代理会在本书后面的模式中讨论。
Table 23.1: List of Different Proxy Types
代理类型目的
远程代理提供对在不同地址空间的远程对象的访问
缓存代理
/服务代理为了提供能够保存目标操作经常用到的结果,代理对象以存储方式保存这些结果。当客户对象请求同一个操作时,代理不需要直接访问目标对象,而是从存贮介质返回操作结果。
防火墙代理使用防火墙代理主要是为了保护目标对象以防止有害客户的访问。同时也可以防止客户访问有害的目标对象。
保护代理提供了不同客户访问不同层次的目标对象的功能。
在创建代理时,定义了一个权限的集合。虽后,这些权限用来限制访问代理的特定部分,如果没有执行方法的权限,客户对象不允许访问特定的方法。
同步代理提供了允许不同的客户对象安全的同步访问目标对象的功能。
计数代理在执行目标对象的方法前,提供了一些审计机制。
代理模式和其他模式
从讨论不同的代理对象中可以看出:代理对象有两个主要的特征:
(1)它介于客户对象和目标对象之间。
(2)它接受客户对象的调用,然后转发调用给目标对象。
在这种情形下,看上去和本书中前面讨论的其他模式有些相似。让我们讨论一下代理模式和一些与它相似的模式之间的相同点和不同点。
代理模式和装饰模式
:
代理模式:
(1)客户对象不能直接访问目标对象
(2)代理对象提供了对目标对象的访问控制(在保护代理中)
(3)代理对象不能再增加其他的功能。
装饰模式:
(1)如果需要,客户对象不能直接访问目标对象。
(2)装饰对象不能控制对目标对象的访问。
(3)装饰对象可以增加额外的功能。
代理模式和外观模式:
代理模式:
(1)代理对象代表一个单一对象。
(2)客户对象不能直接访问目标对象。
(3)代理对象提供了对于单一目标对象的访问控制。
外观模式:
(1)外观对象代表了对象的一个子系统。
(2)如果必要,客户对象可以直接访问子系统中的对象。
(3)一个外观对象提供了一个对子系统组件的简单的、高层次的接口.
代理模式和责任链模式:
代理模式:
(1)代理对象代表了一个单一的对象。
(2)克辉请求首先被代理对象所接受,但是不直接被代理对象处理。(3)客户请求总是被传递给目标对象。
(4)假设客户与服务器正常工作,可以保证请求会得到响应,
责任链模式:
(1)责任链包括很多对象。
(2)接受客户请求的对象首先处理请求。
(3)近当现在的接收者不能处理请求时,客户请求才被传递给下一个对象。(4)不能保证请求会得到响应。也就是请求已经到达责任链尾,担仍然没有被处理。
在Java中,远程方法调用(RMI)充分的利用了远程代理模式,让我们快速的浏览一下远程方法调用(RMI)的概念和远程方法调用(RMI)通信过程应用的组件。
RMI:快速浏览
RMI使客户对象像访问本地对象一样访问远程对象并调用其方法成为可能。(如图23.1)
Figure 23.1: Client’s View of Its Communication with a Remote Object Using RMI
下面是为实现RMI功能而一起协作的不同组件。
(1)远程接口(Remote Interface)??一个远程对象必须实现一个远程接口(这个接口扩展java.rmi.Remote)。远程接口声明可以被客户访问的远程对象的方法。换句话说,远程接口可以看成远程对象对客户的视图。
需求(要求):
1) 扩展java.rmi.Remote
2) 在远程接口中定义的所有方法必须声明抛出java.rmi.RemoteException 异常。
(2)远程对象(Remote Object)??远程对象负责实现在远程接口中定义的方法。
需求(要求):
1)必须提供远程接口的实现。
2)必须扩展java.rmi.server.UnicastRemoteObject类。
3)必须有一个没有参数的构造函数。
4)必须与一个服务器相关联。通过调用零参数的构造函数,服务器创建远程对象的一个实例。
(3) RMI注册表(RMI Registry)??RMI注册表提供了保持不同远程对象的地址空间。
1)远程对象需要存储在一个客户可以通过命名引用(Name reference)来访问它的RMI注册表中。
2)一个给定的命名引用仅可以存储一个对象。
(4)客户(Client)??客户是一个试图访问远程对象的应用程序。
1)必须可以感知被远程对象实现的接口。
2)通过命名引用(Name reference)在RMI注册表中可以查到远程对象。一旦查到远程对象的引用,调用这个引用上的方法。
(5)RMIC (Java RMI 桩编译器)Java RMI stub compiler??一旦远程对象编译成功,RMIC(Java RMI 桩编译器)可以生成远程对象的桩类文件(stub)和框架类文件(skeleton)。桩类文件(stub)和框架类文件(skeleton)从编译的远程对象类中产生。这些桩类文件(stub)和框架类文件(skeleton) 使客户对象以无缝的方式访问远程对象成为可能。
下面这部分描述客户对象和远程对象如何通信。
RMI通信机制:
一般地,客户对象不能按通常方式直接访问远程对象。为了使客户对象像访问本地对象一样访问远程对象的服务,RMIC(Java RMI 桩编译器)生成的远程对象的桩文件(stub)和远程接口需要拷贝到客户机器上。