天天看点

《设计模式修炼真经》08 — 代理模式

1、定义

代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问;

代理模式也叫做委托模式,是一种使用频率非常高的设计模式;在生活中有一种职业可以非常好的体现代理模式 — 中介;

2、类图

代理模式的通用类图如下:

《设计模式修炼真经》08 — 代理模式

代理模式的结构很简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问控制,各部分组成如下:

  • 抽象主题(Subject)类:可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求;
  • 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象;
  • 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

3、代码实现

抽象主题 的Java代码实现如下:

interface Subject {
    void Request();
}      

真实主题 的Java代码实现如下:

class RealSubject implements Subject {
    public void Request() {
        System.out.println("访问真实主题方法...");
    }
}      

代理类 的Java代码实现如下:

class Proxy implements Subject {
    private RealSubject realSubject;
    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        preRequest();
        realSubject.Request();
        postRequest();
    }
    public void preRequest() {
        System.out.println("访问真实主题之前的预处理。");
    }
    public void postRequest() {
        System.out.println("访问真实主题之后的后续处理。");
    }
}      

4、特点

优点:

1、职责清晰,降低了系统的耦合度;

真实主题就是实际的业务逻辑,无需关心其他业务逻辑,通过代理完成整个完整的功能,软件功能划分简洁清晰。

2、高扩展性;

代理对象可以扩展目标对象的功能;

3、保护敏感对象;

在使用者与目标对象之间起到一个中介作用和保护目标对象的作用;

缺点:

1、会造成系统设计中类的数量增加;

2、代理对象容易成为性能瓶颈;

3、增加了系统的复杂度;

5、适用场景

当无法或不想直接引用某个对象或访问某个对象存在困难时,可以通过代理对象来间接访问;

使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。

6、动态代理

上述的代理模式,我们需要自己实现代理类,这是方式叫做静态代理;

静态代理存在两个缺点:

  • 真实主题与代理主题一一对应,增加真实主题也要增加代理;
  • 设计代理类之前真实主题必须事先存在,缺少灵活性;

采用动态代理模式可以解决以上问题;动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。

而在Java 中,JDK帮我们封装好了动态代理相关的类,可以非常轻松的实现动态代理;

6.1 Java中的动态代理类

Java动态代理类位于java.lang.reflect包下,主要涉及到以下一个接口和一个类:

1、InvocationHandler 接口

该接口中仅定义了一个方法

public object invoke(Object obj,Method method, Object[] args)      

参数obj 指 被代理类,method是 被代理的方法,args为该方法的参数数组;

2、Proxy 动态代理类

该类即为动态代理类,其中主要包含以下内容:

//构造函数,用于给内部的InvocationHandler赋值
protected Proxy(InvocationHandler h)

//获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有接口的数组
static Class getProxyClass (ClassLoaderloader, Class[] interfaces)

//返回被代理类的一个实例,返回后的Object可以当作被代理类使用
static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)      

6.2 JDK动态代理机制的使用

主要分为两个步骤:

第一步:实现InvocationHandler

public class InvocationHandlerImpl implements InvocationHandler
{
    //要代理的真实对象
    private Object subject;
 
    //构造方法,给我们要代理的真实对象赋初值
    public InvocationHandlerImpl(Object subject)
    {
        this.subject = subject;
    }
 
    /**
     * 集中处理动态代理类上的所有方法调用。
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        //在代理真实对象前可以添加一些自己的操作
        ....
        //执行要调用的方法
        Object returnValue = method.invoke(subject, args);
        //在代理真实对象后我们也可以添加一些自己的操作
        ....
        return returnValue;
    }
}      

第二步:调用Proxy.newProxyInstance生成动态代理类实例

public class DynamicProxyDemo
{
    public static void main(String[] args)
    {
        //代理的真实对象
        Subject realSubject = new RealSubject();
        
        //创建InvocationHandlerImpl对象
        InvocationHandler handler = new InvocationHandlerImpl(realSubject);
 
        //生成动态代理类实例
        ClassLoader loader = realSubject.getClass().getClassLoader();
        Class[] interfaces = realSubject.getClass().getInterfaces();
        Subject subject = (Subject) Proxy.newProxyInstance(loader, interfaces, handler);
         //使用动态代理类实例
         subject.doSomething();
    }
}      

6.3 JDK动态代理机制的原理

此部分不是本文的重点,感兴趣的同学可以自行阅读源码,大体上可以分为四步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

本文参考了:Java JDK 动态代理(AOP)使用及实现原理分析

我的视频课

下面是我录制的一些视频课,欢迎大家围观~《设计模式修炼真经》​ 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结,代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。 本套课程深入介绍了经典的23种设计模式,并加入了自己的感悟,希望大家能够彻底掌握设计模式,写出最好的代码,达到无招胜有招的境界,最终超越这23种设计模式。

《彻底搞定JVM》​ JVM是Java中重要的也是较难理解的内容; 面试者对JVM的了解程度某种程度上反映了面试者技术深度,所以JVM也是面试时经常考察的内容; 本课程从JVM运行流程、数据运行时区域组成部分、类加载机制、垃圾回收机制、内存模型、常见面试题讲解等角度出发,帮你彻底搞定JVM,拿下心仪Offer;

《Android性能优化参考》 本课程包含了Android中的App启动优化、UI优化、内存优化、图片优化、耗电量等常见的性能优化场景,通过学习此课程,你将对整个Android性能优化体系有清晰的认识。

性能优化作为Android高级开发的必备技能,也是大厂面试必考的题目,是体现一个人技术深度最好的试金石。

《面试之排序算法》 排序算法是我们面试被问到最多的基础算法,本课程详细介绍了七种排序算法,包括插入排序、选择排序、冒泡排序、谢尔排序、快速排序、堆积排序和二路并归排序。每种算法都详细介绍了核心思想、详细步骤、时间复杂度和代码实现,希望帮助大家深入理解排序算法,搞定面试!

《Android HyBrid App开发实战》 本课程为Android HyBrid App开发实战课程,由浅入深,从三种App的历史和特点开始,介绍了Android WebView的使用、Java和JS交互的原生方式、著名的WebView安全漏洞、JSBridge的原理和使用,最后通过一个网上商城的实战综合全部内容,让同学们掌握并深入理解Android HyBrid App开发。

《AI导论》​ 介绍人工智能AI的诞生历史和到现在为止的不同发展阶段;介绍了AI领域中常见的名词概念和其关系,包括机器学习、深度学习、神经网络结构搜索 NAS、生成对抗网络 GAN等;最后对AI发展做出展望。 本课程属于导论课程,旨在帮助同学们从宏观层面把握AI,建立AI的知识体系。

《Java注解精讲》​ 本课程详细介绍了Java中的注解机制,包括注解的定义和分类,注解的使用和自定义,注解的源码和架构分析; 本课程语言简单凝练,视频短小精悍,让你一次彻底搞懂Java注解!

《Java反射精讲》​ 反射是Java中重要的也是较难理解的内容;

本课程从反射的定义、作用、原理和使用出发,全方位帮你彻底搞定反射;

您的点赞是我前进的动力~