一、角色。
1、主题类Subject:接口或者抽象类或者类。
2、真实类RealSubject:继承或实现了主题类Subject。
3、代理类Proxy:继承或实现了主题类Subject,同时直接持有真实类对象。
二、更高更。
1、
2、
三、模式的结构
代理模式的UML类图如下:
代理模式的结构比较简单,包含如下三个角色:
- Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。
- Proxy(代理主题角色):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;在代理主题角色中提供一个与真实主题角色相同的接口,以便在任何时候都可以替代真实主题;代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。通常,在代理主题角色中,客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。
- RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。
四、典型代码
代理模式的结构图比较简单,但是在真实的使用和实现过程中要复杂很多,而且它有很多变化。
抽象主题类声明了真实主题类和代理类的公共方法,它可以是接口、抽象类或具体类,客户端针对抽象主题类编程,一致性地对待真实主题和代理主题,典型的抽象主题类代码如下:
public interface Subject { void request(); }
真实主题代码:
public class RealSubject implements Subject { public void request() { // todo } }
代理类代码:
public class Proxy implements Subject { private RealSubject realSubject = new RealSubject();//真实主题的引用 public void request() { postRequest(); realSubject.request(); postRequest(); } public void preRequest(){ //todo } public void postRequest(){ //todo } }
五、代理模式与装饰者模式异同:
看了代理模式的类图,相信会发现代理模式和装饰者模式类图很像。对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。
那它们之间有什么区别呢?
1、首先,代理模式和装饰者模式的意图是不一样的。装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。
2、其次,当使用代理模式的时候,常常在一个代理类中创建一个对象的实例。而使用装饰器模式的时候,通常的做法是将原始对象作为一个参数传给装饰者的构造器。
3、最后,使用代理模式,代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。
六、优点和缺点
1、优点
代理模式的共同优点如下:
-
能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
-
客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性。
此外,不同类型的代理模式也具有独特的优点,例如:
-
远程代理为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。
-
虚拟代理通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。
-
缓冲代理为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。
-
保护代理可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。
2、缺点
代理模式的主要缺点如下:
-
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。
-
实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。
-
代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。可以通过动态代理改进。
七、适用环境
代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:
-
当客户端对象需要访问远程主机中的对象时可以使用远程代理。
-
当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
-
当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
-
当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
-
当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。
八、模式应用
Spring在JAVA开发中占有举足轻重的地方,其中的AOP是一大功能特色,Spring aop的实现就用到了代理模式。感兴趣的可以去了解一下。
###############################################################################################
明星代理人案例。
###############################################################################################
时代在发展,我们发现,现在不少明星都开始进行微访谈之类的,有越来越多的参与捐赠等。新的一天开始了,首先看下新的一天的日程安排:
1 interface Schedule{
2
3 public void weiTalk();
4
5 public void donation();
6
7 }
Schedule接口定义了今天的形成安排,主要包括微访谈和捐款。那么看一下实现此接口的明星类定义:
1 class Star implements Schedule {
2
3 @Override
4 public void weiTalk() {
5 System.out.println("开始微访谈");
6 }
7
8 @Override
9 public void donation() {
10 System.out.println("开始捐款");
11 }
12
13 }
我们知道,现在明星一般的身边都有一个人,称之为经纪人,负责明星的工作安排及各种事物处理等。一般明星到哪,相应的经纪人也就到哪。我们来定义一个经纪人:
1 class Broker implements Schedule {
2 private Schedule star;
3
4 public Broker() {
5 star = new Star();
6 }
7
8 public Broker(Schedule star) {
9 this.star = star;
10 }
11
12 @Override
13 public void weiTalk() {
14 System.out.println("陪着明星参加为访谈");
15 star.weiTalk();
16 }
17
18 @Override
19 public void donation() {
20 System.out.println("陪着明星捐款");
21 star.donation();
22 }
23
24 }
我们知道,Broker虽然也需要参加微访谈和捐款,但都是陪着明星的,例如现在正在微博访谈,网友问了一个问题:你希望你的小neinei尽快长大呢?WZ回答,当然不是很希望啦。于是经纪人在WZ的微博中回复网友:当然不是很希望啦。
我们发现,Broker对象实现的方法中实际上调用的还是相应所持有的Star对象引用中相应的方法。好,假如正在微访谈过程中,小neinei睡醒了,嚷嚷着爸爸去哪了,于是WZ只得马上跑过去哄自己心爱的小neinei。可这时候网友们还在提问啊,怎么办呢,经纪人总不能擅自做主张的直接回答网友问题吧,于是向网友解释:小neinei醒了,WZ去哄她睡觉了,微访谈顺延到21:30。
又或者在去参与捐赠会的路上,突然剧组那边有更重要的发布会要Star过去,这时候捐赠会主办方打电话过来询问代理们是不是快要到了,代理当即回答,Star临时有更重要的事情要处理,就不去参加了,当然,钱肯定还是会给的。
在外界看来,一般情况下无论是接商务广告还是友情出演,首先都是联系Broker的,等Broker和Star商量后作出决定并有Broker对外回复。
上面整个过程中,外界与Star是不能直接接触的,或者说要先有代理的安排,Broker和Star之间的关系是代理和被代理的关系。这种设计模式我们称之为代理模式。可能有人会说,怎么感觉跟装饰器模式那么像呢?确实,在代码层次而言,两者确实比较接近。而主要的不同在于两个模式背后所蕴含的思想:
装饰器模式主要用来替代继承,为的是给一个现有的类增加新的功能,客户端关心的是装饰后的类所具有的功能;而代理模式为的是对被代理对象提供访问控制,客户端关心的实际上还是被代理对象所具有的功能。
https://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html
#########################################################################