享元和代理模式

news2024/11/25 16:45:27

文章目录

  • 享元模式
    • 1.引出享元模式
        • 1.展示网站项目需求
        • 2.传统方案解决
        • 3.问题分析
    • 2.享元模式
        • 1.基本介绍
        • 2.原理类图
        • 3.外部状态和内部状态
        • 4.类图
        • 5.代码实现
          • 1.AbsWebSite.java 抽象的网站
          • 2.ConcreteWebSite.java 具体的网站,type属性是内部状态
          • 3.WebSiteFactory.java 网站工厂,根据类型,获取对应类型的网站
          • 4.User.java 使用网站的用户,是外部状态
          • 5.Client.java
          • 6.结果
        • 6.小结
    • 3.享元模式在Integer的应用
  • 代理模式
    • 1.基本介绍
        • 1.介绍
        • 2.简单类图
    • 2.静态代理
        • 1.基本介绍
        • 2.类图
        • 3.代码实现
          • 1.目录结构
          • 2.ITeacherDao.java 被代理的接口
          • 3.TeacherDao.java 被代理的实现类
          • 4.TeacherDaoProxy.java 静态代理类
          • 5.Client.java
          • 6.结果
    • 2.动态代理(JDK代理)
        • 1.基本介绍
        • 2.类图
        • 3.代码实现
          • 1.ITeacherDao.java 被代理的接口
          • 2.TeacherDao.java 被代理的类
          • 3.ProxyFactory.java 代理工厂,返回动态代理对象
          • 4.Client.java
          • 5.结果
    • 3.Cglib代理
        • 1.基本介绍
        • 2.注意事项
        • 3.类图
        • 4.引入四个jar包
        • 5.代码实现
          • 1.目录结构
          • 2.TeacherDao.java 被代理的类
          • 3.ProxyFactory.java 返回代理对象的工厂
          • 4.Client.java
          • 5.结果
        • 6.几种变体

享元模式

1.引出享元模式

1.展示网站项目需求

image-20240606191730892

2.传统方案解决

image-20240606191827445

3.问题分析

image-20240606192028943

2.享元模式

1.基本介绍

image-20240606192335106

2.原理类图

image-20240606193100266

3.外部状态和内部状态

image-20240606193331455

4.类图

image-20240606204034058

5.代码实现
1.AbsWebSite.java 抽象的网站
package com.sun;

/**
 * Description: 抽象的网站
 * @Author sun
 * @Create 2024/6/6 19:45
 * @Version 1.0
 */
public abstract class AbsWebSite {
    public abstract void use(User user);
}
2.ConcreteWebSite.java 具体的网站,type属性是内部状态
package com.sun;

/**
 * Description: 具体的网站
 * @Author sun
 * @Create 2024/6/6 19:46
 * @Version 1.0
 */
public class ConcreteWebSite extends AbsWebSite {

    // 网站的发布类型
    private String type = "";

    // 在创建网站时把具体的类型传进来
    public ConcreteWebSite(String type) {
        this.type = type;
    }

    @Override
    public void use(User user) {
        System.out.println("网站的发布类型为:" + type + user.getName() + "在使用中");
    }
}
3.WebSiteFactory.java 网站工厂,根据类型,获取对应类型的网站
package com.sun;

import java.util.HashMap;

/**
 * Description: 网站的工厂类,根据需求,返回一个具体的网站
 * @Author sun
 * @Create 2024/6/6 19:49
 * @Version 1.0
 */
public class WebSiteFactory {

    // 一个集合,充当池的作用
    private HashMap<String, ConcreteWebSite> pool = new HashMap<>();

    public AbsWebSite getWebsiteCategory(String type) {
        // 如果池中没有包含对应类型的对象,就创建一个对象,放到池中
        if (!pool.containsKey(type)) {
            pool.put(type, new ConcreteWebSite(type));
        }
        // 只要到这里了就必然可以拿到对象
        return (AbsWebSite) pool.get(type);
    }

    // 获取池中的网站总数
    public int getWebSiteCount() {
        return pool.size();
    }
}
4.User.java 使用网站的用户,是外部状态
package com.sun;

/**
 * Description: 享元模式中的外部状态
 * @Author sun
 * @Create 2024/6/6 20:12
 * @Version 1.0
 */
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
5.Client.java
package com.sun;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/6 20:02
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) {
        // 创建一个工厂类
        WebSiteFactory webSiteFactory = new WebSiteFactory();
        // 要一个以新闻形式发布的网站
        AbsWebSite webSite = webSiteFactory.getWebsiteCategory("新闻");
        webSite.use(new User("tom"));
        // 要一个以博客形式发布的网站,后面即使要更多相同类型的网站,都会直接从池中获取,而不会创建新的实例
        AbsWebSite webSite2 = webSiteFactory.getWebsiteCategory("博客");
        webSite2.use(new User("jack"));
        AbsWebSite webSite3 = webSiteFactory.getWebsiteCategory("博客");
        webSite3.use(new User("lisa"));
        AbsWebSite webSite4 = webSiteFactory.getWebsiteCategory("博客");
        webSite4.use(new User("milan"));
        int webSiteCount = webSiteFactory.getWebSiteCount();
        System.out.println("webSiteCount = " + webSiteCount);
    }
}
6.结果

image-20240606202939498

6.小结

image-20240606203809699

3.享元模式在Integer的应用

image-20240606203140153

代理模式

1.基本介绍

1.介绍

image-20240607185048981

2.简单类图

image-20240607185359392

2.静态代理

1.基本介绍

image-20240607185536038

2.类图

image-20240607190752822

3.代码实现
1.目录结构

image-20240607191357755

2.ITeacherDao.java 被代理的接口
package com.sun.staticproxy;

/**
 * Description: 接口
 * @Author sun
 * @Create 2024/6/7 19:05
 * @Version 1.0
 */
public interface ITeacherDao {
    void teach();
}
3.TeacherDao.java 被代理的实现类
package com.sun.staticproxy;

/**TeacherDaoProxy.java
 * Description: 实现类
 * @Author sun
 * @Create 2024/6/7 19:06
 * @Version 1.0
 */
public class TeacherDao implements ITeacherDao{
    @Override
    public void teach() {
        System.out.println("老师正在授课中");
    }
}
4.TeacherDaoProxy.java 静态代理类
package com.sun.staticproxy;

/**
 * Description: 代理TeacherDao
 * @Author sun
 * @Create 2024/6/7 19:06
 * @Version 1.0
 */
public class TeacherDaoProxy implements ITeacherDao{

    // 使用构造器进行聚合
    private ITeacherDao teacherDao;

    public TeacherDaoProxy(ITeacherDao teacherDao) {
        this.teacherDao = teacherDao;
    }

    @Override
    public void teach() {
        System.out.println("代理开始");
        teacherDao.teach();
        System.out.println("代理结束");
    }
}
5.Client.java
package com.sun.staticproxy;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/7 19:11
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) {
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(new TeacherDao());
        teacherDaoProxy.teach();
    }
}
6.结果

image-20240607191930143

2.动态代理(JDK代理)

1.基本介绍

image-20240607192125894

2.类图

image-20240607192440028

3.代码实现
1.ITeacherDao.java 被代理的接口
package com.sun.dynamic;

/**
 * Description: 被代理的接口
 * @Author sun
 * @Create 2024/6/7 19:25
 * @Version 1.0
 */
public interface ITeacherDao {

    void teach(String name);

}
2.TeacherDao.java 被代理的类
package com.sun.dynamic;

/**
 * Description: 实现类
 * @Author sun
 * @Create 2024/6/7 19:06
 * @Version 1.0
 */
public class TeacherDao implements ITeacherDao {

    @Override
    public void teach(String name) {
        System.out.println(name + "老师正在授课中");
    }

}
3.ProxyFactory.java 代理工厂,返回动态代理对象
package com.sun.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * Description: 动态代理对象,可以对其代理的对象的任意方法添加任意操作
 * @Author sun
 * @Create 2024/6/7 19:27
 * @Version 1.0
 */
public class ProxyFactory {

    // 构造器聚合一个目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 给目标对象,生成一个代理对象
    public Object getProxyInstance() {
        /**
         * 参数说明:
         * ClassLoader loader:指定当前目标对象使用的类加载器
         * Class<?>[] interfaces:是目标对象实现的接口类型,使用泛型方法确认类型
         * InvocationHandler h:是事件处理,当使用代理对象调用目标对象的方法时会触发
         */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            /**
             * method:目标方法的Method对象,可以用来调用目标任何方法
             * args:目标方法的参数,也就是动态代理对象调用目标任何方法时传入的参数
             * @return 返回调用目标方法的返回值,也可以返回null
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("method = " + method + ", args = " + Arrays.toString(args));
                System.out.println("动态代理开始");
                /*
                invoke方法的第一个参数是目标对象,第二个参数的目标方法的参数
                 */
                Object result = method.invoke(target, args);
                System.out.println("动态代理结束");
                return result;
            }
        });
    }
}
4.Client.java
package com.sun.dynamic;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/7 19:47
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) {
        // 创建一个目标对象
        ITeacherDao target = new TeacherDao();
        // 得到代理对象
        ITeacherDao proxy = (ITeacherDao) new ProxyFactory(target).getProxyInstance();
        // 使用代理对象调用方法
        proxy.teach("李华");
    }
}
5.结果

image-20240607200723913

3.Cglib代理

1.基本介绍

image-20240608192032151

2.注意事项

image-20240608192430278

3.类图

image-20240608193428124

4.引入四个jar包

image-20240608194008692

5.代码实现
1.目录结构

image-20240608195233301

2.TeacherDao.java 被代理的类
package com.sun.cglib;

/**
 * Description: 被代理的类
 * @Author sun
 * @Create 2024/6/8 19:37
 * @Version 1.0
 */
public class TeacherDao {

    public void teach(String name) {
        System.out.println(name + "老师授课中,使用的是cglib代理,不需要实现接口");
    }
}
3.ProxyFactory.java 返回代理对象的工厂
package com.sun.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/8 19:38
 * @Version 1.0
 */
public class ProxyFactory implements MethodInterceptor {

    // 构造器聚合一个目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 返回目标对象的代理对象
    public Object getProxyInstance() {
        //1.创建一个工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(target.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类对象
        return enhancer.create();
    }

    /**
     * 当使用代理对象调用目标对象的函数时,就会跳到这个函数,跟之前动态代理时类似
     * @param o
     * @param method 代理对象调用的目标对象的函数
     * @param args 函数的参数
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理模式开始");
        // 调用目标对象的函数
        System.out.println("method = " + method);
        System.out.println("args = " + args);
        Object returnVal = method.invoke(target, args);
        System.out.println("cglib代理结束");

        return returnVal;
    }
}
4.Client.java
package com.sun.cglib;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/8 19:50
 * @Version 1.0
 */
public class Client {
    public static void main(String[] args) {
        // 创建一个目标对象
        TeacherDao teacherDao = new TeacherDao();
        // 得到目标对象的代理对象
        ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
        TeacherDao proxyInstance = (TeacherDao) proxyFactory.getProxyInstance();
        // 使用代理对象来调用目标对象函数,则会被代理
        proxyInstance.teach("小明");
    }
}
5.结果

image-20240608195343395

6.几种变体

image-20240608195602019

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1827615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tensorflow-GPU工具包了解和详细安装方法

目录 基础知识信息了解 显卡算力 CUDA兼容 Tensorflow gpu安装 CUDA/cuDNN匹配和下载 查看Conda driver的版本 下载CUDA工具包 查看对应cuDNN版本 下载cuDNN加速库 CUDA/cuDNN安装 CUDA安装方法 cuDNN加速库安装 配置CUDA/cuDNN环境变量 配置环境变量 核验是否安…

后端开发中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…

Python 全栈系列253 再梳理flask-celery的搭建

说明 最近做了几个实验&#xff0c;将结论梳理一下&#xff0c;方便以后翻看。 1 flask-celery 主要用于数据流的同步任务&#xff0c;其执行由flask-aps发起&#xff0c;基于IO并发的方法&#xff0c;达到资源的高效利用&#xff0c;满足业务上的需求。2 目前部署环境有算网…

餐厅点餐系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;用户管理&#xff0c;店家管理&#xff0c;广告管理 店家账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品管理&#xff0c;广告管…

基于System-Verilog的流水灯设计与仿真

文章目录 一、system Verilog1.语言基本介绍2.过程赋值和连续赋值 二、编写testbench仿真1.流水灯testbench2.2位全加器3.实验结果 一、system Verilog 1.语言基本介绍 像 Verilog 和 VHDL 之类的硬件描述语言 (HDL) 主要用于描述硬件行为&#xff0c;以便将其转换为由组合门…

Python中的数据可视化:绘制三维线框图plot_wireframe()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 Python中的数据可视化&#xff1a; 绘制三维线框图 plot_wireframe() [太阳]选择题 在上面的代码中&#xff0c;plot_wireframe() 方法用于绘制什么类型的图形&#xff1f; import matplot…

无公网ip、服务器无法上网如何实现外网访问

在ipv4的大环境下&#xff0c;公网ip和车牌号一样抢手&#xff0c;一个固定公网ip价格非常昂贵&#xff0c;中小企业承担不起&#xff0c;也不愿意在上面投入&#xff1b;同时勒索病毒日益猖獗&#xff0c;企业信息化负责人为了保证数据安全性&#xff0c;干脆禁止服务器上外网…

LM339模块电路故障查询

最近的电路测试中出现一个问题&#xff0c;如果不接液晶屏&#xff0c;LM339输入端是高电平&#xff0c;如果接了液晶屏&#xff0c;输入端就是低电平&#xff0c;即使在输入端加了上拉电阻&#xff0c;还是如前面的结论&#xff0c;如果越过LM339,直接和后级电路连接&#xff…

纽约华尔街Wall Street 简介

中文版 华尔街简介 华尔街位于纽约市曼哈顿下城&#xff0c;是全球最重要的金融中心之一。它代表了美国的金融市场&#xff0c;并且是许多重要金融机构的所在地。以下是对华尔街的概述&#xff1a; Source: Google Map 历史背景 起源&#xff1a;"华尔街"这个名字…

springboot原理篇-springboot

springboot原理篇-springboot&#xff08;三&#xff09; 一、起步依赖 虽然我是直接学习springboot的&#xff0c;没有经历过使用spring开发&#xff0c;但是鉴于我还学习了c,对依赖这方面真的一言难尽&#xff01;springboot起步依赖解决依赖问题我实在是羡慕&#xff01; 直…

移动端超超超详细知识点总结(Part4)

rem基础 1. rem单位 rem (root em)是一个相对单位&#xff0c;类似于em&#xff0c;em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如&#xff0c;根元素&#xff08;html&#xff09;设置font-size12px; 非根元素设置width:2rem;则换成px表示就是24p…

条件语句与循环结构

引言 条件语句和循环结构是C语言中构建程序逻辑的基本工具。它们允许程序根据条件执行不同的代码块和重复执行某些操作。本篇文章将详细介绍C语言中的条件语句和循环结构&#xff0c;包括if、else、switch语句&#xff0c;以及for、while、do-while循环的使用&#xff0c;帮助读…

【猫狗分类】Pytorch VGG16 实现猫狗分类1-数据清洗+制作标签文件

Pytorch 猫狗分类 用Pytorch框架&#xff0c;实现分类问题&#xff0c;好像是学习了一些基础知识后的一个小项目阶段&#xff0c;通过这个分类问题&#xff0c;可以知道整个pytorch的工作流程是什么&#xff0c;会了一个分类&#xff0c;那就可以解决其他的分类问题&#xff0…

JWT令牌、过滤器Filter、拦截器Interceptor

目录 JWT令牌 简介 JWT生成 解析JWT 登陆后下发令牌 过滤器(Filter) Filter快速入门 Filter拦截路径 过滤器链 登录校验Filter-流程 拦截器(Interceptor) Interceptor 快速入门 拦截路径 登录校验流程 JWT令牌 简介 全称:JSON Web Token(https://iwt.io/) …

可信计算和数字水印技术

可信计算 可信计算可信计算基础概述可信计算关键技术要素可信性认证可信计算优劣 数字水印技术数字版权保护技术 可信计算 可信计算基础概述 可信计算&#xff08;Trusted Computing&#xff0c;TC&#xff09;&#xff1a;在计算和网络通信系统中广泛使用的、基于硬件安全模块…

驱动开发(五):Linux内核定时器

驱动开发系列文章&#xff1a; 驱动开发&#xff08;一&#xff09;&#xff1a;驱动代码的基本框架 驱动开发&#xff08;二&#xff09;&#xff1a;创建字符设备驱动 驱动开发&#xff08;三&#xff09;&#xff1a;内核层控制硬件层 驱动开发&#xff08;四&#xff…

LabVIEW盾构机状态监测

随着城市化的加速&#xff0c;地铁成为了城市交通的重要组成部分。为了保障地铁施工安全和效率&#xff0c;提出了一种基于LabVIEW的地铁施工盾构异常状态监测方法。该方法利用LabVIEW软件进行数据采集和处理&#xff0c;通过异常监测技术实时监控盾构机的运行状态&#xff0c;…

【纯干货级教程】深度学习根据loss曲线进行分析调参

相信很多刚刚接触目标检测系列算法小伙伴跑深度学习算法时会有许多困惑&#xff0c;比如训练得出的loss曲线有什么意义&#xff1f;训练的一些参数要如何设置选择&#xff1f;选择哪个算法模型作为baseline、选择哪个参数量/复杂度/深度的模型进行训练最为合适&#xff1f; 本…

Apache IoTDB进行IoT相关开发实践

当今社会&#xff0c;物联网技术的发展带来了许多繁琐的挑战&#xff0c;尤其是在数据库管理系统领域&#xff0c;比如实时整合海量数据、处理流中的事件以及处理数据的安全性。例如&#xff0c;应用于智能城市的基于物联网的交通传感器可以实时生成大量的交通数据。据估计&…

15. 第十五章 类和对象

15. 类和对象 到现在你已经知道如何使用函数组织代码, 以及如何使用内置类型来组织数据. 下一步将学习面向对象编程, 面向对象编程使用自定义的类型同时组织代码和数据. 面向对象编程是一个很大的话题, 需要好几章来讨论.本章的代码示例可以从↓下载, https://github.com/Alle…