设计模式之代理模式
- 格式:pdf
- 大小:152.68 KB
- 文档页数:3
设计模式之代理模式
代理模式英⽂名叫Proxy Pattern
看下Proxy的含义
[ˈprɑ:ksi]
n.代表权;代理⼈,代替物;委托书;
主要表达的就是代表、代替、委托的意思。
我对这个模式的理解是这样的:
⼀个服务或者是⼀个功能,⼀个对象。由于某种⾃⾝或者外界的原因,不能直接暴露出来,⽽是需要另外⼀个对象做⼀下跳转(也不⼀定是完全的跳转)。并且在这个过程中,最终实现功能或者是解决问题的实体并没有发⽣改变。
光说概念的话会⽐较抽象,我们举⼏个⽣活中的例⼦:
1>房产中介
如果户主打算拍卖掉房⼦,因此需要每天发⼴告、发消息,然后接待买家看房,和买家讨价还价。
这样的模式,相对来说⽐较简单,(也是很多新⼿喜欢的直接)。但是户主需要和每⼀个买家都进⾏接触。增加⼀个新的买家,就需要重新试探。流失⼀个买家,⼜有实时跟踪。这导致作为卖家的户主所要处理的事情越来越腌肿,买家关注了太多⾃⼰只⽤⼀次或者根本⽤不到的技能。
因此就需要引⼊⼀个代理:房产中介。
卖家将房⼦的信息:钥匙、报价、区间、卖房时间等整体告诉中介后。中介将所有的信息进⾏处理后公布出来。买房⼈再从中介处获取到⾃⼰所需要的信息,然后再通过中介与卖家沟通。
这样卖家就不需要再关注任何买房动态。只需要按照事先⾃⼰考虑的结果与代理进⾏商议即可。
2>明星经纪⼈
3>办事处
对于跨国企业来说,涉及到的业务往往是全球化的,很多业务往来存在政治、地区、时差等限制。因此有时这些机构就设置⼀个办事处,⽤来作为这些企业在当地的⼀个委托⼈,来治谈业务等。
这样做很好的体现出了对内提⾼内聚、对外降低耦合:
户主、明星、跨国企业都可以最⼤限度的聚焦于⾃⾝业务对外;(内聚)
户主、明星、跨国企业都不再需要过多的感知外界业务,通过代理这⼀层进⾏封装过滤,将真正属于户主(过户)、明星(演出)、跨国企业(⽣产制造)的业务传递给被代理⼈来操作。⽽对于外界来说⼤部分情况下,外界调⽤者并不感知到代理的存在,所有的事情与直接和被代理⼈谈是⼀样的。(解耦)
模式的结构可以理解为下图的样⼦:
可以看出代理⽅和被代理⽅都实现了⼀个对外接⼝。
这个接⼝是被代理⽅所有展⽰的所有⽅法。
调⽤⽅持有该接⼝的实现:代理⼈。
可以通过如下代码来深度理解代理模式:
调⽤⽅
1 public class Invoker
2 {
3 public static void main(String[] args)
4 {
5 ISuperStar ronaldo = new SuperStarProxy("ronaldo");
6 ronaldo.negotiate();
7 ronaldo.signContract();
8 ISuperStar messi = new SuperStarProxy("messi");
9 messi.negotiate();
10 messi.signContract();
11 }
12 }
代理类
1 public class SuperStarProxy implements ISuperStar
2 {
3 private ISuperStar superStar = new SuperStar();
4 private String superStarName;
5
6 public SuperStarProxy(String superStarName) 7 {
8 this.superStarName = superStarName;
9
10 }
11
12 @Override
13 public void signContract()
14 {
15 superStar.signContract();
16 }
17
18 @Override
19 public void negotiate()
20 {
21 superStar.negotiate();
22 }
23
24 }
被代理类
1 public class SuperStar implements ISuperStar
2 {
3 @Override
4 public void signContract()
5 {
6 // to do sth
7 return;
8 }
9
10 @Override
11 public void negotiate()
12 {
13 // to do sth
14 return;
15 }
16 }
接⼝
1 public interface ISuperStar
2 {
3 /**
4 * 签约
5 */
6 public void signContract();
7
8 /**
9 * 谈判
10 */
11 public void negotiate();
12 }
代理模式的⼏个⽤途:
1、进⾏安全代理控制
被代理⽅和调⽤⽅有时存在于两个不同的安全域中,我们需要通过⼀个安全过滤鉴权的管道进⾏控制。这种情况下就可以使⽤代理来完成安全鉴权的功能。
举个例⼦:⽐如公司的外⽹访问,有时需要设置⼀个⽹络代理
2、虚拟代理进⾏延迟加载
有时初始化数据时,需要过多的初始化数据时,可以通过代理延缓这种加载,等到真正调⽤时,再初始化。举个例⼦:有时⽤流量看公众号⽂章时,如果是GIF,系统会暂时只加载⼀个静态的图⽚,当⽤户确定要看该GIF时,再点击图⽚,加载真正的GIF,静态的图⽚就相当于是⼀个虚拟代理。
3、远程⼯作代理
有时我们要调⽤⽹络另外⼀侧的⼀个接⼝,每⼀个开发者都需要⾃⼰实现⼀个该远程⽹络的交互,交互⽅式是千差万别的。这时我们就会使⽤⼀个远程的⼯作代理,这个代理就是⼀个接⼝的实现。我们可以先使⽤该代理进⾏开发,同时开发者也感知不到接⼝真正的⼯作状态。当我们调⽤这个远程的代理时,代理在内部就⾃动的与远程的接⼞进⾏交互。⽽本地的业务逻辑并不能感知到。
举个例⼦:数据库包中的JDBC,该包由数据库⼚商提供,我们的业务代码只和JDBC进⾏交互,并不会直接使⽤各种⽹络协议与数据库进⾏交互
4、管控有时我们需要添加接⼝访问⽇志、接⼝耗时、频次等。就可以在原有实现的基础上,加⼀层代理。将这些逻辑推倒代理中实现,降低业务实现类的代码污染。
代理模式的缺点:
通过代理模式,我们可以看出,该模式在内聚封装的同时,将⼀部分的业务逻辑移植到了代理⼈处。虽然降低了调⽤⽅和实现⽅之间的耦合,但是加⼊了⼀层新的耦合,就是代理⽅和调⽤⽅之间的耦合。当有任何逻辑变更时,都需要修改代理⽅,因此代理模式在降低耦合的同时,会导致代理类变得越来越雕肿、业务越来越复杂。
扩展:
由于代理⽅也是接⼝的实现⽅,随着接⼝的变化,代理⽅都需要添加新的逻辑实现。⽽这种实现需要在系统运⾏前就已经搭配,并实现完成。因此这种模式也称为静态代理模式。我们在这个时候,需要⽀持⼀种动态的,最好可以⼀劳永逸的代理⽅式。这种⽅式可以⽀持简单的相同的逻辑处理,之后就直接进⾏透传即可。这种代理模式我们称之为动态代理。这个我会在后边的⽂章中介绍。