享元和代理模式

文章目录

  • 享元模式
    • 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《C语言》动态内存管理

文章目录 一、动态内存分配二、关于动态内存开辟的函数1、malloc2、free3、calloc4、realloc 三、常见的动态内存的错误1、对NULL指针的解引用操作2、对动态开辟空间的越界访问3、对非动态开辟内存使用free释放4、释放free释放一块动态开辟的内存的一部分5、对同一块动态内存多…

Ubuntu基础-VirtualBox安装增强功能

目录 零. 前言 一. 安装 1.点击安装增强功能 2.点击光盘图标 3.复制到新文件夹 4.运行命令 5.重启系统 6.成果展示 二. 打开共享 1.共享粘贴 ​编辑2.共享文件夹 三.总结 安装步骤 打开共享粘贴功能&#xff1a; 打开共享文件夹功能&#xff1a; 零. 前言 在使用…

设计模式-代理模式Proxy(结构型)

代理模式&#xff08;Proxy&#xff09; 代理模式是一种结构型模式&#xff0c;它可以通过一个类代理另一个类的功能。代理类持有被代理类的引用地址&#xff0c;负责将请求转发给代理类&#xff0c;并且可以在转发前后做一些处理 图解 角色 抽象主题&#xff08;Subject&…

upload-labs第九关教程

upload-labs第九关教程 一、源代码分析代码审计::$DATA介绍 二、绕过分析特殊字符::$data绕过上传eval.php使用burpsuite抓包进行修改放包&#xff0c;查看是否上传成功使用中国蚁剑进行连接 一、源代码分析 代码审计 $is_upload false; $msg null; if (isset($_POST[submi…

抖音a_bogus,mstoken爬虫逆向补环境2024-06-15最新版

抖音a_bogus,mstoken爬虫逆向补环境2024-06-15最新版 接口及参数 打开网页版抖音&#xff0c;右键视频进入详情页。F12打开控制台筛选detail&#xff0c;然后刷新网页&#xff0c;找到请求。可以发现我们本次的参数目标a_bogus&#xff0c;msToken在cookie中可以获得&#xf…

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

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

分布式微服务: springboot底层机制实现

springboot底层机制实现 搭建SpringBoot底层机制开发环境ConfigurationBean会发生什么,并分析机制提出问题: SpringBoot 是怎么启动Tomcat, 并可以支持访问Controller源码分析: SpringApplication.run()SpringBoot的debug流程 实现SpringBoot底层机制[Tomcat启动分析 Spring容…

在向量数据库中存储多模态数据,通过文字搜索图片

在向量数据中存储多模态数据&#xff0c;通过文字搜索图片&#xff0c;Chroma 支持文字和图片&#xff0c;通过 OpenClip 模型对文字以及图片做 Embedding。本文通过 Chroma 实现一个文字搜索图片的功能。 OpenClip CLIP&#xff08;Contrastive Language-Image Pretraining&…

课设--学生成绩管理系统(一)

欢迎来到 Papicatch的博客 文章目录 &#x1f349;技术核心 &#x1f349;引言 &#x1f348;标识 &#x1f348;背景 &#x1f348;项目概述 &#x1f348; 文档概述 &#x1f349;可行性分析的前提 &#x1f348;项目的要求 &#x1f348;项目的目标 &#x1f348;…

Java入门4: 泛型和集合

Java入门4: 泛型和集合 MangoGO 芒狗狗 目录 4 泛型和集合4.1 泛型4.2 Collection4.3 List4.4 ArrayList4.5 Map4.6 HashMap4.7 Set 和 HashSet4.8 Collections参考代码4 泛型和集合 Java 使用集合来组织和管理对象,本节我们重点讲解泛型和集合。主要介绍 Collection、List、A…

C#医院体检系统源码 PEIS源码 系统核心功能、特点、类型、设备对接-PACS放射科设备对接:DR、CT、MRI、钼靶。

C#医院体检系统源码 PEIS源码 系统核心功能、特点、类型、设备对接-PACS放射科设备对接:DR、CT、MRI、钼靶。 体检系统是为体检中心、医院体检科等体检机构专门开发的全流程管理系统。该系统通过软件实现检测仪器数据的自动提取&#xff0c;内置多级医生工作台&#xff0c;旨在…

远程连接服务器的工具?

远程连接服务器工具是现代工作环境中不可或缺的工具之一。它允许用户通过网络远程访问和控制远程服务器&#xff0c;为用户提供了更加便捷和高效的工作方式。无论是远程办公、远程维护还是云计算&#xff0c;远程连接服务器工具都发挥着重要的作用。 在众多远程连接服务器工具…

LabVIEW RT在非NI硬件上的应用与分析

LabVIEW RT&#xff08;实时操作系统&#xff09;可运行在非NI&#xff08;National Instruments&#xff09;硬件上&#xff0c;如研华工控机&#xff0c;但需要满足特定硬件要求。本文从硬件要求、开发和运行差异、可靠性、稳定性、优势和成本等多角度详细分析在非NI硬件上运…

【Mac】Luminar Neo for mac(图像编辑软件)软件介绍及同类型软件比较

Luminar Neo软件介绍 Luminar Neo 是一款由 Skylum 开发的功能强大的照片编辑软件&#xff0c;专为摄影师和摄影爱好者设计。它适用于 Mac 和 Windows 平台&#xff0c;提供了一系列先进的编辑工具和功能&#xff0c;使用户能够轻松提升和优化他们的照片。以下是 Luminar Neo …

沸点 | LDBC与SIGMOD联合研讨,推动图数据库创新与标准化

当地时间6月9日&#xff0c;国际基准官方平台关联数据基准委员会&#xff08;LDBC&#xff0c;Linked Data Benchmark Council&#xff09;与SIGMOD 2024&#xff08;是全球最具国际影响力的数据管理、数据处理和数据存储领域的学术顶会之一&#xff0c;ACM SIGMOD/Big Data in…

非关系型数据库NoSQL数据层解决方案 之 redis springboot整合与读写操作 2024详解以及window版redis5.0.14下载百度网盘

redis下载安装以及基本使用 下载地址 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;0410 一个名对应一个数值 内存级 在内存里进行操作 准备启动 我们现在就有一个redis客户端的服务器了 我们再启动一个cmd 操作redis数据库 redis里面的基本数据类型有五种 …

用Canvas绘制2D平面近大远小的马路斑马线

用Canvas绘制2D平面近大远小的马路斑马线 设置canvas和上下文&#xff1a; 首先&#xff0c;你需要创建一个元素&#xff0c;并获取其2D渲染上下文。 绘制斑马线&#xff1a; 使用fillRect或strokeRect方法绘制斑马线。你可以通过循环和计算来绘制多条具有不同宽度和间隔的…

LeetCode20.有效的括号

题目描述 分析 我们刚上来的思路可能是&#xff1a;找出这三种括号的个数 如果都是偶数 说明匹配 但是这里还有一个顺序问题 比如 " )( "这样是不匹配的&#xff01; 所以这种思路不可取&#xff01; 我们想 如果遇到左括号&#xff0c;把他读到一个顺序表中&#…

等级考试3-2021年3月题

作业&#xff1a; #include <iostream> using namespace std; int chonghe(int,int,int,int); int main(){int a[1000],b[1000];int n,ma0;cin>>n;for(int i0;i<n;i){cin>>a[i]>>b[i];}for(int i0;i<n;i){for(int ji1;j<n;j){mamax(ma,chongh…

Python酷库之旅-比翼双飞情侣库(10)

目录 一、xlrd库的由来 二、xlrd库优缺点 1、优点 1-1、支持多种Excel文件格式 1-2、高效性 1-3、开源性 1-4、简单易用 1-5、良好的兼容性 2、缺点 2-1、对.xlsx格式支持有限 2-2、功能相对单一 2-3、更新和维护频率低 2-4、依赖外部资源 三、xlrd库的版本说明 …