• 15.代理模式


    1.何为代理模式?

    代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。
    简单来说,现在比如有一个对象A, 有一个对象B, 本来是对象B直接可以调用对象A实现某种功能的,但是由于特殊的原因对象B无法直接调用对象A来完成功能,而是通过对象C将对象A的调用封装后暴露接口给对象B调用才能完成我们想要的功能,这时我们就可以说对象C是对象A的代理对象。

    2. 通过实际的例子来学习代理模式

    2.1 静态代理

    静态代理在编码时期将代理类写死,然后将由用户自己创建代理类的实例进行使用。
    例如如下设计:
    其中ChinesePerson的代理类Translators只能在编码时期提前定义好,然后供客户端使用。
    在这里插入图片描述

    Person接口

    package ProxyPattern.staticProxy;
    public interface Person {
        public void sayHello();
        public void howAreYou();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ChinesePerson类

    package ProxyPattern.staticProxy;
    
    public class ChinesePerson implements Person{
        public void sayHello(){
            System.out.println("哈喽啊!!");
        }
        public void howAreYou(){
            System.out.println("你吃饭了嘛?");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    现在我们想通过调用ChinesePerson获得相应的英文翻译,这时,我们就可以通过代理的方式完成:
    我们可以新建一个代理类:
    Translators类

    package ProxyPattern.staticProxy;
    /**
     * 英文翻译者类
     */
    public class Translators implements Person{
        Person ChinesePerson = new ChinesePerson();
        public void sayHello(){
            ChinesePerson.sayHello();
            System.out.println("哈喽啊 : Hello!!");
        }
        public void howAreYou(){
            ChinesePerson.howAreYou();
            System.out.println("你吃了吗 :how are you");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    然后只需要执行下面的代码就能获得想要的效果:

    package ProxyPattern.staticProxy;
    public class StaticTest {
        public static void main(String[] args) {
            Person person = new Translators();
            person.howAreYou();
            person.sayHello();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    这便是静态代理,静态代理是以死代码的方式完成代理功能的,优点是实现简单,缺点是灵活性差。
    代码地址如下:
    设计模式/src/main/java/ProxyPattern/staticProxy/StaticTest.java · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)

    2.2 动态代理

    而动态代理便解决了静态代理的缺点,能让我们在系统运行时期动态的生成代理类供我们使用,但是动态代理的一个缺点是: 理解和实现起来比较复杂。
    好在JDK本身实现了动态代理的实现,我们只需学习它如何使用即可。动态代理可以在程序运行期间创建代理类来让我们使用(只要我们遵守其规则进行编程即可)

    2.2.1 使用JDK动态代理机制进行编程

    同样是和静态代理一样的例子,我们用动态代理的方式进行实现。
    在这里插入图片描述

    它的原理是: 首先我们认为的编写一个ProxyHandler实现指定接口InvocationHandler,然后使用Proxy类的newProxyInstance方法将ProxyHandler和指定需要被代理的类进行自动生成,生成一个我们需要的代理类并创建代理类的实例返回指定接口引用,然后我们就可以使用代理类了。

    代码地址如下:
    设计模式/src/main/java/ProxyPattern/dynamicProxy/DynamicTest.java · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)
    在这里插入图片描述

    同样,除了JDK的代理支持,还有一些代理框架,比如Cglib,想要了解到请看我的这一个博客:
    3.如何实现AOP?(静态代理,Jdk动态代理,cglib动态代理,自定义动态代理)_程序员小牧之的博客-CSDN博客_aop是如何实现的

    2.3 远程代理

    前面我们所学习的都是在一个系统里的本地代理,那么在实际开发中,我们可能并不想要进行本地代理,我们有时候需要远程代理调用,那么如何进行远程调用代理呢? 这个是个问题。

    代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。

    好在JDK也为我们提供了一个技术:RMI技术,远程方法调用,该技术能让我们像调用本地方法一样调用远程系统中的方法。

    RMI详细学习,请看下面博客:
    [RMI远程服务制作]

    2.3.1 接到了糖果机老板的需求

    在上一节,我们用状态模式帮糖果机老板设计了一个厉害的系统之后,糖果机的老板还希望能通过远程的方式实时查询糖果的属性,比如看糖果机中的库存。
    这时,远程代理的作用就显示了哈哈哈。员工A接到这个需求后,立马将设计做了出来:
    在这里插入图片描述

    代码地址如下:
    设计模式/src/main/java/ProxyPattern/third · 严家豆/设计模式 - 码云 - 开源中国 (gitee.com)
    运行效果如下:
    服务端:
    在这里插入图片描述

    客户端:
    在这里插入图片描述

    代理模式为另一个对象提供提供一个替身或占位符(代理对象)以控制对这个对象的访问。

  • 相关阅读:
    HTML实现轮播图
    深入理解Kafka核心设计及原理(二):生产者
    如何利用Python开发自动发布文章脚本?记录开发万媒易发的心路历程
    05 - 雷达的发展与应用
    2021.09青少年软件编程(Python)等级考试试卷(三级)
    JetPack组件Databinding
    PyCharm中常用的快捷键用法详解
    1.4.15 实验15:ospf多区域NSSA
    Apache Calcite - 使用内置函数
    CRM软件哪个好?国内外6大顶级CRM软件盘点
  • 原文地址:https://blog.csdn.net/c1776167012/article/details/125469894