Java设计模式设计模式

《设计模式》代理模式

2019-08-25  本文已影响0人  敏捷Studio

基本介绍

定义

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

介绍

UML类图

代理模式UML类图

角色说明:

具体实现

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

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、静态代理与动态代理比较

静态代理优点

静态代理的缺点

动态代理的优点

动态代理的缺点

模式总结

应用场景

优点

缺点

Android中的源码分析

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

ActivityManager相关类的结构图

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

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

上一篇 下一篇

猜你喜欢

热点阅读