定义

为其他对象提供一种代理以控制对这个对象的访问。

结构和说明

结构型模式-代理模式 - 图1

示例代码

  1. public class ProxyDemo {
  2. /**
  3. * 抽象的目标接口,定义具体的目标对象和代理公用的接口
  4. */
  5. public static interface Subject {
  6. /**
  7. * 示意方法: 一个抽象的请求方法
  8. */
  9. void request();
  10. }
  11. /**
  12. * 具体的目标对象,是真正被代理的对象
  13. */
  14. public static class RealSubject implements Subject {
  15. @Override
  16. public void request() {
  17. // 执行具体的功能处理
  18. }
  19. }
  20. /**
  21. * 代理对象
  22. */
  23. public static class Proxy implements Subject {
  24. /**
  25. * 持有被代理的具体的目标对象
  26. */
  27. private RealSubject realSubject;
  28. /**
  29. * 构造方法,传入被代理的具体的目标对象
  30. *
  31. * @param realSubject 被代理的具体的目标对象
  32. */
  33. public Proxy(RealSubject realSubject) {
  34. this.realSubject = realSubject;
  35. }
  36. @Override
  37. public void request() {
  38. // 在转调具体的目标对象前,可以执行一些功能处理
  39. realSubject.request();
  40. // 在转调具体的目标对象后,可以执行一些功能处理
  41. }
  42. }
  43. public static class Client {
  44. public static void main(String[] args) {
  45. Subject subject = new Proxy(new RealSubject());
  46. subject.request();
  47. }
  48. }
  49. }

调用顺序

结构型模式-代理模式 - 图2

特点

代理模式在客户和被客户访问的对象之间,引入了一定程度的间接性,客户是直接使用代理,让代理来与被访问的对象进行交互。不同的代理类型,这种附加的间接性有不同的用途,也就具有不同的特点。

  • 远程代理: 隐藏了一个对象存在与不同地址空间的事实,也即是客户通过远程代理去访问一个对象,根本不关心这个对象在哪里,也不关心如何通过网络去访问到这个对象。从客户的角度来讲,它只是在使用代理对象而已。
  • 虚代理: 可以根据需要来创建“大”对象,只有到必须创建对象的时候,虚代理才会创建对象,从而大大加快程序运行速度,并节省资源。通过虚代理可以对系统进行优化。
  • 保护代理: 可以在访问一个对象前后,执行很多附加的操作,除了进行权限监控之外,还可以进行很多跟业务相关的处理,而不需要修改被处理的对象。也就是说,可以通过代理来给目标对象增加功能。
  • 智能指引: 和保护代理类似,也是允许在访问一个对象前后,执行很多附加操作,这样一来就可以做很多额外的事情,比如引用计数等。

思考

本质

控制对象访问。

何时选用

  • 需要为一个对象在不同地址空间提供局部代表的时候,可以使用远程代理。
  • 需要按照需要创建开销很大的对象的时候,可以使用虚代理。
  • 需要控制对原始对象的访问的时候,可以使用保护代理。
  • 需要在访问对象执行一些附加操作的时候,可以使用智能指引代理。

相关模式

  • 代理和适配器模式

这两个模式有一定的相似性,但也有差异。
这个两个模式有相似性,他们都为另外一个对象提供间接性的访问,而且都是从自身以外的一个接口向这个对象转发请求。
但是从功能上,这个两个模式是不一样的。适配器模式主要用来解决接口之间不匹配的问题,它通常是为所适配的对象提供一个不同的接口;而代理模式会实现和目标对象相同的接口。

  • 代理和装饰模式

这两个模式从实现上相似,但是功能上是不同的。
装饰模式的实现和保护代理的实现是类似的,都是在转调其他对象的前后执行一定的功能。但是他们的目的和功能都是不同的。
装饰模式的目的是为了让你不生成子类就可以给兑现添加职责,也就是为了动态地增加功能;而代理模式的主要目的是控制对对象的访问。