Head First 设计模式--Proxy

Chapter 11 --代理模式

                                   控制对象的访问

 

1. 远程代理就好比“远程对象的本地代表”。所谓远程对象,是指在不同的Java虚拟机堆中的对象(或者说在不同的地址空间运行的远程对象)。所谓本地代表,是指一种可以由本地方法调用的对象,其行为会转发到远程对象中。


2. 客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的“代理”对象上的方法,再由代理处理所有网络通信的低层信息。


3. RMI提供了客户辅助对象(stub)和服务辅助对象(skeleton),为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写任何网络或I/O代码。客户程序调用远程方法就和在本地JVM上对对象进行正常的方法调用一样。

 

4. 制作远程服务

 

(1) 制作远程接口:远程接口定义出可以让客户远程调用的方法。客户将用他作为服务的类类型。stub和实际的服务都实现此接口。=>MyService.java

(2) 制作远程的实现:这是做实际工作的类,为远程接口中定义的远程方法提供了真正的实现。这是客户真正想要调用方法的对象。=>MyServiceImpl.java

(3) 利用rmic产生的stub和skeleton:这就是客户和服务的辅助类。你不需要自己创建这些类,因为当你运行rmic工具时,这都会自动处理。=> rmic MyServiceImpl

(4) 启动RMI registry:rmiregistry就像是电话簿,客户可以从中查到代理(stub)的位置。=>rmiregistry

(5) 开始远程服务:你必须让服务对象开始运行。你的服务实现类会去实例化一个服务的实例,并将这个服务注册到RMI registry。注册之后,这个服务就可以供客户调用了。 =>java MyServiceImpl



代理模式:
为另一个对象提供一个替身或占位符以控制对这个对象的访问。

proxy
Structure
  • subject: 它为RealSubject和Proxy提供了接口。因为Proxy和RealSubject都实现了Subject接口,这就允许任何客户都可以想处理RealSubject对象一样地处理Proxy对象,使得Proxy可以在RealSubject出现的地方取代它。
  • RealSubject: 它是真正做事的对象,Proxy会控制对RealSubject的访问。
  • Proxy: Proxy持有RealSubject的引用,在必要时它可以将请求转发给RealSubject。客户和RealSubject的交互都必须通过Proxy,Proxy控制了对Realsubject的访问,有时,Proxy还会负责RealSubject对象的创建和销毁。

5. 使用代理模式创建代表(representative)对象,让代表对象控制某对象的访问,被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。
(1) 远程代理控制访问远程对象。
(2) 虚拟代理控制访问创建开销大的资源。
(3) 保护代理基于权限控制对资源的访问。

虚拟代理
虚拟代理作为创建开销大的对象的代表。虚拟代理经常直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。

6. Java在java.lang.reflect包中有自己的代理支持,利用这个包你可以再运行时动态地创建一个代理类,实现一个或多个接口,并将方法的调用转发到你所指定的类。因为实际的代理类是在运行时创建的,我们称这个Java技术为动态代理。

7. 可以利用Java的动态代理创建一个保护代理。因为Java已经为我们创建了Proxy类,所以你需要有办法来告诉Proxy类你要做什么。因为Proxy不是你直接实现的,你不能将代码放在Proxy类中,那么只能放在InvocationHandler中。InvocationHandler的工作是响应代理的任何调用。
保护代理是一种根据访问权限决定客户可否访问对象的代理。

protect proxy
Structure
  • Proxy: Proxy是由Java产生的,而且实现了完整的Subject接口。
  • InvocationHandler: 由开发者提供InvocationHandler,Proxy上的任何方法调用都会被传入此类。InvocationHandler控制对RealSubject方法的访问。
  • 代理现在包含Proxy和InvocationHandler两个类。

8. 代理类有一个静态方法,叫做isProxyClass()。此方法的返回值如果为true,表示这是一个动态代理类。除此之外,代理类还会实现特定的某些接口。


其他代理
(1) 防火墙代理(Firewall Proxy):控制网络资源的访问,保护主题免于“坏客户”的侵害。常用于公司的防火墙系统。
(2) 智能引用代理(Smart Reference Proxy):当主题被引用时,进行额外的动作,例如计算一个对象被引用的次数。
(3) 缓存代理(Caching Proxy):为开销大的运算结果提供暂时存储,它也允许多个客户共享结果,以减少计算或网络延迟。常用于Web服务器代理,以及内容管理与出版系统。
(4) 同步代理(Synchronization Proxy):在多线程的情况下为主题提供安全的访问。用于JavaSpaces,为分布式环境内的潜在对象集合提供同步访问控制。
(5) 复杂隐藏代理(Complexity Hiding Proxy):用来隐藏一个类的复杂集合的复杂度,并进行控制访问。有时也称为外观代理(Facade Proxy)。复杂隐藏代理和外观模式是不一样的,因为代理控制访问,而外观模式只提供另一组接口。
(6) 写入时复制代理(Copy-On-Write Proxy):用来控制对象的复制,方法是延迟对象的复制,直到客户真的需要为止。这是虚拟代理的变体。


本章小结:
  • 代理模式为另一个对象提供代表,以便控制客户对对象的访问,管理访问的方式有许多种。
  • 远程代理管理客户和远程对象之间的交互。
  • 虚拟代理控制访问实例化开销大的对象。
  • 保护代理基于调用者控制对对象方法的访问。
  • 代理模式有许多变体,例如:缓存代理、同步代理、防火墙代理和写入时复制代理。
  • 代理在结构上类似于装饰者,但是目的不同。
  • 装饰者模式为对象加上行为,而代理则是控制访问。
  • Java内置的代理支持,可以根据需要建立动态代理,并将所有调用分配到所选的处理器。
  • 就和其他的包装者(warpper)一样,代理会造成你的设计中类的数目增加。

猜你喜欢

转载自eriol.iteye.com/blog/1100954