Java设计模式之代理模式

概述

代理模式(Proxy)也称为委托模式,是结构型设计模式
代理在我们日常生活中也并不少见,比如代理上网,代驾等等,所谓代理就是一个人或者机构代表另一个人或者机构采取行动,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

定义

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

使用场景

  • 无法或者不想直接访问某个对象,或者访问某个对象存在困难时
  • 需要注意的是为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口

UML

Java设计模式之代理模式_第1张图片

其中涉及到的角色有:

  • Subject : 抽象主题类,声明真实主题与代理的共同接口方法,既可以是一个抽象类,也可以是接口
  • RealSubject : 真实主题类,被委托类(被代理类),定义了代理所表示的真实对象,由其执行具体的业务逻辑方法
  • ProxySubject : 代理类,委托类或代理类,持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题的相应接口方法执行
  • Client : 客户类,使用代理类的类型

实例

接下来通过一个简单的实例来说明一下Java中的代理模式,
如下是一个通过律师代理仲裁的小李子.

  • 首先定义Subject对象
public interface ILawsuit {
  //提交申请
  void submit();

  //进行举证
  void burden();

  //开始辩护
  void defend();

  //诉讼完成
  void finish();
}
  • 具体的主题类,实现了Subject接口
public class XiaoMin implements ILawsuit {

  private static final String TAG = "XiaoMin";

  @Override public void submit() {
    Log.d(TAG, "submit: -->" + "老板拖欠工资,特此申请仲裁");
  }

  @Override public void burden() {
    Log.d(TAG, "burden: -->" + "小明提供了合同书和过去一年的工资流水");
  }

  @Override public void defend() {
    Log.d(TAG, "defend: -->" + "证据确凿,不需要辩护什么了...");
  }

  @Override public void finish() {
    Log.d(TAG, "finish: -->" + "诉讼成功!判决老板七日内结算工资");
  }
}
  • 代理类,小明自己不懂法律,于是请了律师来帮忙
public class Lawyer implements ILawsuit {
  private ILawsuit mILawsuit;//持有一个具体的被代理者的对象

  public Lawyer(ILawsuit _ILawsuit) {
    mILawsuit = _ILawsuit;
  }

  @Override public void submit() {
    mILawsuit.submit();
  }

  @Override public void burden() {
    mILawsuit.burden();
  }

  @Override public void defend() {
    mILawsuit.defend();
  }

  @Override public void finish() {
    mILawsuit.finish();
  }
}
  • 客户类,具体的调用方式
ILawsuit xiaomin = new XiaoMin();
    ILawsuit lawyer = new Lawyer(xiaomin);
    lawyer.submit();
    lawyer.burden();
    lawyer.defend();
    lawyer.finish();

代理分为动态代理和静态代理,如上是简单的静态代理,动态代理和静态代理的区别主要体现在代理类的生成时机

静态代理在代码运行前我们的代理类的 class 编译文件就已经存在,而动态代理则通过反射在运行时动态生成代理者.
java中为我们提供了方便的InvocationHandler用于方便的实现动态代理
如下是动态代理的生成方式

  • 动态代理类
public class DynamicProxy implements InvocationHandler {

  private Object mObject;

  public DynamicProxy(Object _object) {
    mObject = _object;
  }

  @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = method.invoke(mObject, args);
    return result;
  }
}
  • 客户端调用
ILawsuit xiaomin = new XiaoMin();
   DynamicProxy dynamicProxy = new DynamicProxy(xiaomin);
   ClassLoader classLoader = xiaomin.getClass().getClassLoader();
   ILawsuit lawyer = (ILawsuit) Proxy.newProxyInstance(classLoader, new Class[] {
       ILawsuit.class
   }, dynamicProxy);

   lawyer.submit();
   lawyer.burden();
   lawyer.defend();
   lawyer.finish();

代理模式的特点

从代码层面可以分为静态代理和动态代理,而从使用范围来看,代理可分为 远程代理,虚拟代理,保护代理,智能代理.
代理模式在很多开源框架中都有应用,可以说是一种细化到很小的一种模式,几乎没什么缺点可言,要真说有什么缺点,那就是类的增多

参考:
Java 动态代理作用是什么?
Android公共技术点之四-Java动态代理

实例代码

DesignPatterns

你可能感兴趣的:(设计模式,Java基础,java设计模式,设计模式,代理模式,动态代理)