美文网首页Java设计模式设计模式
《设计模式》代理模式

《设计模式》代理模式

作者: 敏捷Studio | 来源:发表于2019-08-25 01:06 被阅读0次

基本介绍

定义

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

介绍

  • 代理模式属于结构型模式。
  • 代理模式也叫委托模式。
  • 生活中,比如代购、打官司等等,实际上都是一种代理模式。

UML类图

代理模式UML类图

角色说明:

  • Subject(抽象主题类):接口或者抽象类,声明真实主题与代理的共同接口方法。
  • RealSubject(真实主题类):也叫做被代理类或被委托类,定义了代理所表示的真实对象,负责具体业务逻辑的执行,客户端可以通过代理类间接的调用真实主题类的方法。
  • Proxy(代理类):也叫委托类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。
  • Client(客户端类):使用代理模式的地方。

具体实现

以海外代购为例,在国内的人想买国外的东西只能去找国外的人去进行代购。

1、创建抽象主题类。人都是有购买这个方法的:

public interface People {
  // 购买
  void buy();
}

2、创建真实主题类。国内的人想购买某些产品,定义具体的购买过程:

public class Domestic implements People {
  @Override
  public void buy() {
    System.out.println("国内要买一个包");
  }
}

3、创建代理类。海外的代购党需要知道是谁(持有真实主题类的引用)想购买啥产品:

public class Oversea implements People {
  // 持有People类的引用
  People mPeople;

  public Oversea(People people) {
    mPeople = people;
  }

  @Override
  public void buy() {
    System.out.println("我是海外代购:");
    // 调用了被代理者的buy()方法
    mPeople.buy();
  }
}

5、客户端测试:

public void test() {
  // 创建国内购买人
  People domestic = new Domestic();
  // 创建海外代购类并将domestic作为构造函数传递
  People oversea = new Oversea(domestic);
  // 调用海外代购的buy()
  oversea.buy();                          
}

输出结果:

我是海外代购:
国内要买一个包

静态代理与动态代理

从代码的角度来分,代理可以分为两种:一种是静态代理,另一种是动态代理

静态代理:就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。上面的例子实现就是静态代理。

动态代理:类的源码是在程序运行期间根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

下面我们实现动态代理,Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法:

1、创建动态代理类

// 实现InvocationHandler接口
public class DynamicProxy implements InvocationHandler {
  // 被代理的对象
  private Object obj;

  public DynamicProxy(Object obj) {
    this.obj = obj;
  }

  // 重写invoke()方法
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("海外动态代理调用方法: " + method.getName());
    // 调用被代理的对象的方法
    Object result = method.invoke(obj, args);
    return result;
  }
}

2、修改客户端的测试方法:

public void test() {
  // 创建国内购买人
  People domestic = new Domestic();
  // 创建动态代理
  DynamicProxy proxy = new DynamicProxy(domestic);
  // 获取ClassLoader
  ClassLoader classLoader = domestic.getClass().getClassLoader();
  // 通过 Proxy 创建海外代购实例 ,实际上通过反射来实现的。
  People oversea = (People) Proxy.newProxyInstance(classLoader, new Class[]{People.class}, proxy);
  // 调用海外代购的buy()
  oversea.buy();
}

3、输出结果:

海外动态代理调用方法: buy
国内要买一个包

4、静态代理与动态代理比较

静态代理优点

静态代理的缺点

  • 静态代理如果接口新增一个方法,除了所有实现类(真实主题类)需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
  • 代理对象只服务于一种类型的对象,如果要服务多类型的对象。必须要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。

动态代理的优点

  • 可以通过一个代理类完成全部的代理功能,接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。当接口方法数量较多时,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
  • 动态代理的应用使我们的类职责更加单一,复用性更强。

动态代理的缺点

  • 不能对类进行代理,只能对接口进行代理,如果我们的类没有实现任何接口,那么就不能使用这种方式进行动态代理(因为$Proxy()这个类集成了Proxy,Java的集成不允许出现多个父类)。

模式总结

应用场景

  • 当一个对象不能或者不想直接访问另一个对象时,可以通过一个代理对象来间接访问。为保证客户端使用的透明性,委托对象和代理对象要实现同样的接口。
  • 被访问的对象不想暴露全部内容时,可以通过代理去掉不想被访问的内容。
  • 根据适用范围,代理模式可以分为以下几种:
    • 远程代理:为一个对象在不同的地址空间提供局部代表,这样系统可以将Server部分的事项隐藏。
    • 虚拟代理:如果要创建一个资源消耗较大的对象,可以先用一个代理对象表示,在真正需要的时候才真正创建。
    • 保护代理:用代理对象控制对一个对象的访问,给不同的用户提供不同的访问权限。
    • 智能引用:在引用原始对象的时候附加额外操作,并对指向原始对象的引用增加引用计数。

优点

  • 代理作为调用者和真实主题的中间层,降低了模块间和系统的耦合性。
  • 可以以一个小对象代理一个大对象,达到优化系统提高运行速度的目的。
  • 代理对象能够控制调用者的访问权限,起到了保护真实主题的作用。

缺点

  • 由于在调用者和真实主题之间增加了代理对象,因此可能会造成请求的处理速度变慢。
  • 实现代理模式需要额外的工作(有些代理模式的实现非常复杂),从而增加了系统实现的复杂度。

Android中的源码分析

Android的源码中多个地方都用到代理模式,比如ActivityManagerProxy这个代理类。鉴于ActivityManager的代码非常复杂,这里就不进行分析了,后面会另开文章进行具体分析,这里主要对ActivityManager中的代理模式进行简单的分析一下。先看下相关类的结构图:

ActivityManager相关类的结构图

由上图可以看到:ActivityManagerProxyActivityManagerNative都是实现IActivityManager这个接口,IActivityManager就是抽象主题了,ActivityManagerProxy一看就是代理类,而真实主题则是ActivityManagerNative,实际上ActivityManagerNative是个抽象类,真正的具体实现是在它的子类ActivityManagerService中。

这里的代理实质是个远程代理,ActivityManagerProxyActivityManagerService是运行在不同的进程空间中的。

相关文章

  • Mybatis代理设计模式(Proxy)与编程实现原理

    最易懂设计模式解析适配器设计模式模板方法设计模式Mybatis多级代理 1. 认识代理模式 1.1 模式定义 给某...

  • 模板方法设计模式(Template Method)

    最易懂设计模式解析适配器设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识模板方法模式 1.1 ...

  • 适配器设计模式(Adapter)

    最易懂设计模式解析模板方法设计模式Mybatis代理设计模式Mybatis多级代理 1. 认识适配器模式 1.1 ...

  • 理解java的代理模式和动态代理

    代理模式 代理模式是23种设计模式之一,属于结构型模式。代理模式是最常见也是最常用的模式之一,只不过有很多设计模式...

  • spring框架中的设计模式二

    在这篇文章中,介绍4种设计模式。结构型设计模式:代理和复合模式。行为型设计模式:策略和模板方法模式。 代理模式 面...

  • 10、结构型模式-代理设计模式

    1、加盟商来啦-你需要掌握的代理设计模式 简介:讲解代理设计模式,让代理帮你完成工作 代理设计模式(Proxy P...

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 动态代理原理解析

    注:源自于Android 一、代理模式 代理模式是java23种设计模式常用的一种设计模式。代理模式是客户端不直接...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 前端设计模式

    JS设计模式一:工厂模式jS设计模式二:单例模式JS设计模式三:模块模式JS设计模式四:代理模式JS设计模式五:职...

网友评论

    本文标题:《设计模式》代理模式

    本文链接:https://www.haomeiwen.com/subject/dcicectx.html