• 第十五章·代理模式


    一、代理模式概述

    由于某些原因,客户端不想或不能直接访问一个对象,此时可以通过一个称为“代理”的第三者来实现间接访问,该方案对应的设计模式被称为代理模式。

    定义如下:

    代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

    二、代理模式结构和实现

    2.1 代理模式结构

    代理模式包含3个角色:

    1. Subject(抽象主题角色):声明了真实主题和代理主题的共同接口。
    2. Proxy(代理主题角色):包含了对真实主题的引用。
    3. RealSubject(真实主题角色):实现了真实的业务操作。

    2.2 代理模式实现

    代理模式有很多种实现,根据目的和实现方式不同可以分为很多种。

    本文demo案例介绍下静态代理和JDK动态代理这两种。

    静态代理

    //抽象主题对象

    public interface Subject {
    
        void request();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    //具体的真实主题对象

    public class RealSubject implements Subject{
        @Override
        public void request() {
            System.out.println("真实主题的业务方法");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    //代理对象

    public class ProxySubject implements Subject{
    
        private Subject subject = new RealSubject();
    
        @Override
        public void request() {
            System.out.println("前置方法代码");
            subject.request();
            System.out.println("后置方法代码");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    动态代理

    //抽象主题对象

    public interface IUserDao {
    
        void save();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    //具体的真实主题对象

    public class UserDao implements IUserDao{
    
        @Override
        public void save() {
            System.out.println("保存了数据");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    //代理对象

    public class IUserDaoFactory {
    
        //代理的目标对象
        private Object target;
    
        public IUserDaoFactory(Object target) {
            this.target = target;
        }
    
        //对目标对象进行动态代理
        public Object getProxyInstance() {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("做一些操作A");
                            Object resultValue = method.invoke(target, args);
                            System.out.println("做一些操作B");
                            return resultValue;
                        }
                    });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    //客户端

    public class Client {
    
        public static void main(String[] args) {
    
            //静态代理
            Subject subject = new ProxySubject();
            subject.request();
    
            //JDK动态代理demo
            IUserDao userDao = new UserDao();
            IUserDaoFactory factory = new IUserDaoFactory(userDao);
            IUserDao proxyUserDao = (IUserDao) factory.getProxyInstance();
            proxyUserDao.save();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    三、代理模式优缺点和适用环境

    3.1 代理模式的优点

    1. 协调调用者和被调用者,在一定程度上降低了系统的耦合度;
    2. 系统具有较好的灵活性和可扩展性,客户端可以针对抽象主题角色进行编程,增加和更换代理类无需修改源码,符合开闭原则。

    3.2 代理模式的缺点

    1. 有些类型的代理模式可能会造成请求的处理速度变慢;
    2. 实现代理模式需要一些额外的工作,而且有些代理模式的实现过程较为复杂。

    3.3 代理模式的适用环境

    代理模式的类型较多,不同类型的代理模式有不同的优缺点,应用于不同的场合。

    1. 客户端对象需要访问远程主机中的对象时,使用远程代理。
    2. 使用较少资源对象代表较大资源对象时,使用虚拟代理。
    3. 控制对象为不同用户提供不同的权限时,使用保护代理。
    4. 为一个对象提供额外的操作,使用智能引用代理。
    5. 为被频繁访问的操作结果提供缓存,加速响应,使用缓存代理。

    【参考文献】:
    本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。

    【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git

  • 相关阅读:
    数据分析综述
    Windows上安装jdk17后没有jre的解决方法
    进化吧,MySQL锁!无锁->偏向锁->轻量级锁->重量级锁(请自动脑补数码宝贝进化音)
    TypeScript(零) —— 简介、环境搭建、第一个实例
    ajax,axios,fetch
    Office project 2007安装
    C语言实现进制转换---十六进制转换十进制、十六进制转换八进制
    [附源码]Python计算机毕业设计SSM开放性实验室网上预约管理(程序+LW)
    串行原理编程,中文编程工具中的串行构件,串行连接操作简单
    volatile 关键字(修饰符 volatile 告诉编译器,变量的值可能以程序未明确指定的方式被改变)
  • 原文地址:https://blog.csdn.net/weixin_44143114/article/details/126514412