设计模式之代理模式

  • 格式: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、管控有时我们需要添加接⼝访问⽇志、接⼝耗时、频次等。就可以在原有实现的基础上,加⼀层代理。将这些逻辑推倒代理中实现,降低业务实现类的代码污染。

代理模式的缺点:

通过代理模式,我们可以看出,该模式在内聚封装的同时,将⼀部分的业务逻辑移植到了代理⼈处。虽然降低了调⽤⽅和实现⽅之间的耦合,但是加⼊了⼀层新的耦合,就是代理⽅和调⽤⽅之间的耦合。当有任何逻辑变更时,都需要修改代理⽅,因此代理模式在降低耦合的同时,会导致代理类变得越来越雕肿、业务越来越复杂。

扩展:

由于代理⽅也是接⼝的实现⽅,随着接⼝的变化,代理⽅都需要添加新的逻辑实现。⽽这种实现需要在系统运⾏前就已经搭配,并实现完成。因此这种模式也称为静态代理模式。我们在这个时候,需要⽀持⼀种动态的,最好可以⼀劳永逸的代理⽅式。这种⽅式可以⽀持简单的相同的逻辑处理,之后就直接进⾏透传即可。这种代理模式我们称之为动态代理。这个我会在后边的⽂章中介绍。