设计模式之代理模式(Proxy)(2)

代理模式是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,其特征是代理类与委托类有同样的接口。

动机:

在软件设计中,使用代理模式的意图也很多,比如因为安全原因需要屏蔽客户端直接访问真实对象,或者在远程调用中需要使用代理类处理远程方法调用的技术细节 (如 RMI),也可能为了提升系统性能,通过控制来延迟对象的创建和实例化,直到真正需要使用该对象才进行创建和实例化。

由于一些对象创建和实例化需要占用大量系统资源,但我们并不能确定用户一定会调用该对象,所以通过延迟对象实例化来减缓系统资源的消耗。例如文档编辑器如word,我们可以在里面插入链接、图片等,但是并不是我们每次打开word时都有创建和实例化这些对象,特别是实例化图片对象很消耗资源,并不需要实例化所有图片。当我们在查看word时,只是看到其中的一部分,所以没有必要实例化所以资源,当我们看下一页时再实例化也不迟。

类型:结构类模式

类图:

代理模式类图

图1 代理模式类图

代理模式角色:

1) 主题接口:定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法;

2) 真实主题:真正实现业务逻辑的类;

3) 代理类:用来代理和封装真实主题;

4) Main:客户端,使用代理类和主题接口完成一些工作。

优点:

 对客户端来说,隐藏了真实对象的细节及复杂性。

 将代理对象与真正被调用的对象分离,在一定程度上降低了系统的耦合度。

 在客户端和目标对象之间起到一个中介作用,这样可以起到保护目标对象的作用,也可以对目标对象调用之前进行其他操作。

 远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的性能与处理速度,可以快速响应并处理客户端请求。

 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。

 安全代理可以控制对真实对象的使用权限。

缺点:

 在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。

 增加了系统的复杂度。

适用场景

1) 远程代理:也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。比如说 WebService,当我们在应用程序的项目中加入一个 Web 引用,引用一个 WebService,此时会在项目中声称一个 WebReference 的文件夹和一些文件,这个就是起代理作用的,这样可以让那个客户端程序调用代理解决远程访问的问题。还有.NET的WCF的远程代理。

2) 虚拟代理:是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。这样就可以达到性能的最优化,比如打开一个网页,这个网页里面包含了大量的文字和图片,但我们可以很快看到文字,但是图片却是一张一张地下载后才能看到,那些未打开的图片框,就是通过虚拟代理来替换了真实的图片,此时代理存储了真实图片的路径和尺寸。

3) 安全代理:用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候。

4) 指针引用:是指当调用真实的对象时,代理处理另外一些事。比如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它,或当第一次引用一个持久对象时,将它装入内存,或是在访问一个实际对象前,检查是否已经释放它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理。

5) 智能指引:当调用真实对象时,代理提供一些额外的操作。如将对象被操作的次数记录起来等。

6) 延迟加载,用代理模式实现延迟加载的一个经典应用就在 Hibernate 框架里面。当 Hibernate 加载实体 bean 时,并不会一次性将数据库所有的数据都装载。默认情况下,它会采取延迟加载的机制,以提高系统的性能。Hibernate 中的延迟加载主要分为属性的延迟加载和关联表的延时加载两类。实现原理是使用代理拦截原有的 getter 方法,在真正使用对象数据时才去数据库或者其他第三方组件加载实际的数据,从而提升系统性能。

7) 缓冲代理:为某一个目标操作提供临时的存储空间,以便更多客户端共享此结果。

8) 防火墙代理:保护目标不让恶意用户接近。

9) 同步化代理:使几个用户能同时使用一个对象而没有冲突。

代理模式分类

1. 静态代理(静态定义代理类,自己静态定义的代理类)

1)优点

可以做到在不修改目标对象的功能前提下,对目标功能扩展。

2)缺点

因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多。同时,一旦接口增加方法,目标对象与代理对象都要维护。

3)静态代理模式角色:

 抽象角色:指代理角色和真实角色对外提供的公共方法,一般为一个接口。

 真实角色:需要实现抽象角色接口,定义了真实角色所要实现的业务逻辑,以便供代理角色调用,真正的业务逻辑在此。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzgswz.html