【软考】设计模式之享元模式

目录

        • 1. 说明
        • 2. 应用场景
        • 3. 结构图
        • 4. 构成
        • 5. 适用性
        • 6. java示例

1. 说明
  • 1.享元设计模式(Flyweight Design Pattern)是一种常见的软件设计模式
  • 2.属于结构型设计模式,对象结构型模式
  • 3.目的:运用共享技术有效地支持大量细粒度的对象
2. 应用场景
  • 1.类的结构改变较少,但经常要增加新的基于该结构的操作
  • 2.需要对某一对象结构的对象进行很多不同的并且不相关的操作,而需要避免让这些操作污染这些对象的类,也不希望在新增操作时修改这些类
3. 结构图

在这里插入图片描述

4. 构成
  • 1.享元模式的结构主要包含一下三个角色:抽象享元(Flyweight)角色、具体享元(Concrete Flyweight)角色和享元工厂(Flyweight Factory)角色
  • 2.抽象享元(Flyweight)角色:通常是一个接口或抽象类,在其中声明了具体享元类公共的方法。这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以设置外部数据(外部状态)。抽象享元角色规定了享元对象的统一接口,使得客户端可以透明地使用具体享元对象。
  • 3.具体享元(Concrete Flyweight)角色:实现了抽象享元类,为其内部状态提供了存储空间。通常,可以结合单例模式来设计具体享元类,为每个具体享元类提供唯一的对象。具体享元对象是可以共享的,它们存储了不会随环境改变而改变的可共享状态。
  • 4.享元工厂(Flyweight Factory)角色:负责创建和管理享元对象。当客户端请求一个享元对象时,享元工厂会检查是否已经存在具有相同内部状态的对象。如果存在,就返回已经存在的对象;如果不存在,就创建一个新的具体享元对象。享元工厂通常提供一个存储享元对象的享元池,用于缓存已经创建的享元对象。
  • 5.并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子结点
  • 6.Client 维持一个对 Flyweight 的引用;计算或存储一个或多个 Flyweight 的外部状态。
5. 适用性
  • 1.一个应用程序使用了大量的对象
  • 2.完全由于使用大量的对象,造成很大的存储开销
  • 3.对象的大多数状态都可变为外部状态
  • 4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
  • 5.应用程序不依赖于对象标识。由于Flyweight对象可以被共享,所以对于概念上明显有别的对象,标识测试将返回真值
6. java示例
  • 1.抽象享元角色声明了具体享元类公共的方法
package com.learning.flyweight.bullet;

/**
 * 子弹的抽象享元类
 */
public interface Bullet {
    /**
     * 开火
     */
    void fire();

    /**
     * 设置子弹位置
     * @param x
     * @param y
     */
    void setPosition(int x, int y);

    /**
     * 重置子弹
     */
    void reset();
} 
  • 2.具体享元角色
package com.learning.flyweight.bullet;

// 具体的子弹享元类
public class BulletImpl implements Bullet {
    private int x;
    private int y;

    @Override
    public void fire() {
        System.out.println("Bullet fired at position (" + x + ", " + y + ")");
    }

    @Override
    public void setPosition(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public void reset() {
        // 在这里重置子弹的状态,例如将其位置设置为默认值
        this.x = 0;
        this.y = 0;
        // 可以添加其他需要重置的字段或状态
    }
}
  • 3.享元工厂角色
package com.learning.flyweight.bullet;

import java.util.ArrayList;
import java.util.List;

// 子弹工厂(享元工厂)
class BulletFactory {
    private List<Bullet> list = new ArrayList<>();
  
    // 获取子弹对象  
    public Bullet getBullet() {  
        if (!list.isEmpty()) {
            // 如果有可用的子弹(即已经回收的子弹),则重用  
            Bullet bullet = list.remove(list.size() - 1);
            bullet.reset(); // 重置子弹状态  
            return bullet;  
        } else {  
            // 如果没有可用的子弹,则创建一个新的子弹  
            return new BulletImpl();  
        }  
    }  
  
    // 回收子弹对象  
    public void recycleBullet(Bullet bullet) {
        list.add(bullet); // 将子弹添加到池中以便将来重用
    }  
}  
  • 4.客户端
package com.learning.flyweight.bullet;

public class Client {

    public static void main(String[] args) {
        BulletFactory bulletFactory = new BulletFactory();
        Bullet bullet = bulletFactory.getBullet();
        bullet.setPosition(100, 200);
        bullet.fire();
        // 一段时间后回收子弹(这里假设子弹在发射后立即回收)

        bulletFactory.recycleBullet(bullet);
        bullet = bulletFactory.getBullet();
        bullet.setPosition(50, 250);
        bullet.fire();
        // 一段时间后回收子弹(这里假设子弹在发射后立即回收)
        bulletFactory.recycleBullet(bullet);
    }
}

  • 5.示例截图
    在这里插入图片描述

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

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

相关文章

【Wireshark傻瓜式安装,Wireshark使用过滤条件】

Wireshark傻瓜式安装&#xff0c;Wireshark使用过滤条件 安装使用wireshark过滤器表达式的规则1.抓包过滤器语法和实例&#xff08;1&#xff09;协议过滤&#xff08;2&#xff09;IP过滤&#xff08;3&#xff09;端口过滤&#xff08;4&#xff09;逻辑运算符&&与、…

后端传给前端的时间字段前端显示不正确

具体问题是什么呢&#xff0c;就比如我后段有一个字段是TimeStamp类型&#xff0c;从数据库中查出数据是下面的样式&#xff1a; 但是前端显示的是下面的格式&#xff1a; 这个的解决方法还是挺多的&#xff0c;那接下来具体来看看吧~ 第一种&#xff1a; 在application.prop…

【数据结构】数组、双链表代码实现

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

迁移篇 | MatrixOne与MySQL全面对比

Part 1 迁移背景 Skyable 自研了物联网私有云平台用于 IoT 设备的数据上报和协议解析&#xff0c;由于管理设备数量的增加导致设备上报的数据量越来越大&#xff0c;架构中原使用的 MySQL 数据库&#xff08;分库分表&#xff09;的部分业务在对设备上报信息进行相关的查询时&…

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling ChatGPT结合实际业务&#xff0c;主要是研发多函数调用&#xff08;Function Calling&#xff09;功能模块&#xff0c;将自定义函数通过ChatGPT 问答结果&#xff0c;实现对应函数执行&#xff0c;再次将结果…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:文本通用)

文本通用属性目前只针对包含文本元素的组件&#xff0c;设置文本样式。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 属性 名称参数类型描述fontColorResourceColor设置字体颜色。 从API version 9开…

VBA更新xlOLELinks链接的值

xlOLELinks是在Excel文档中插入对象的链接&#xff0c;该链接能够显示被插入文档的数据&#xff0c;通常情况下链接的数值会自动更新&#xff0c;但有时更新也会不及时或失效&#xff0c;这时就需要手动更新&#xff0c;如下图&#xff1a; 以插入Word文档为例&#xff0c;使用…

【漏洞复现】Laykefu客服系统任意文件上传

漏洞描述 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞,而且当请求中Cookie中的”user_name“不为空时即可绕过登录系统后台,未经身份验证的攻击者可利用此问题,上传后门文件,获取服务器权限。 免责声明 技术文章仅供参考,任何个人和组织使用网络…

js【深度解析】代码的执行顺序

代码的分类 我们将每一句要执行的 js 代码当做一个任务&#xff0c;则 js 代码可以按照其执行方式的不同&#xff0c;按下图分类 同步任务&#xff1a;立即执行的代码异步任务&#xff1a;延迟执行的代码 微任务&#xff1a;被放入微任务队列&#xff08;micro task queue&…

【记录37】VueBaiduMap 踩坑一

截图 错误 Error in callback for watcher “position.lng”: “TypeError: Cannot read properties of undefined (reading ‘setPosition’)” 解释 回调观察程序“content”时出错&#xff1a;“TypeError:无法读取未定义的属性&#xff08;读取’setContent’&#xff09;”…

设计模式-行为型模式-模版方法模式

模板方法模式&#xff0c;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[DP] 模板方法模式是通过把不变行为搬移到超类&#xff0c;去除子类中的重复代码来体现它的优势。 //首…

L-2:插松枝(Python)

作者 陈越 单位 浙江大学 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送…

《汇编语言》第3版(王爽)实验9

第9章 实验9 编程&#xff1a;在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串 ‘welcome to masm!’ assume cs:code,ds:datadata segmentdb welcome to masm!,0 data endscode segmentstart:mov ax,data mov ds,ax ;ds指向data段mov ax,0B800H ;显存空间从B800H…

LeetCode_24_中等_两两交换链表中的节点

文章目录 1. 题目2. 思路及代码实现&#xff08;Python&#xff09;2.1 递归2.2 迭代 1. 题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换…

windows11编译FFmpeg源码完整步骤

1.安装MSYS2 下载并安装MSYS2 安装GCC GCC安装成功 克隆FFmpeg源码 打开MSYS2终端并进入ffmpeg文件夹,然后输入./configure回车开始生成makefile

JavaEE——简单认识JS(Web API)

文章目录 一、认识什么是 WebAPI二、认识事件三、操作元素1. innerHTML 属性2. 获取 / 修改元素内容3. 获取 / 修改 元素属性4. 获取 / 修改 表单元素属性5. 获取 / 修改 样式属性6. 创建 / 删除元素 一、认识什么是 WebAPI 1.什么是API 在我们了解 WebAPI 之前&#xff0c;我们…

苍穹外卖学习-----2024/03/09

1.菜品分页查询 代码在这里 分页查询菜品 2.删除菜品 [链接]param 1、概览 本文将带你了解 Spring 中 RequestParam 注解的用法。 简单地说&#xff0c;可以使用 RequestParam 从请求中提取查询参数、表单参数甚至是多个参数。 2、示例端点 假设我们有一个端点 /api/foos&a…

二叉树遍历(前中后序的递归/非递归遍历、层序遍历)

二叉树的遍历 1. 二叉树的前序、中序、后序遍历 前、中、后序遍历又叫深度优先遍历 注&#xff1a;严格来说&#xff0c;深度优先遍历是先访问当前节点再继续递归访问&#xff0c;因此&#xff0c;只有前序遍历是严格意义上的深度优先遍历 首先需要知道下面几点&#xff1a; …

Spring学习 基础(三)MVC

5、Spring MVC 传统Web模式&#xff1a; Model:系统涉及的数据&#xff0c;也就是 dao 和 bean。View&#xff1a;展示模型中的数据&#xff0c;只是用来展示。Controller&#xff1a;处理用户请求都发送给 &#xff0c;返回数据给 JSP 并展示给用户。 随着 Spring 轻量级开发…

Vue项目实战-空间论坛(2)

项目实战 实现userlist页面 获取userlist列表&#xff0c;可使用ajax,axios 实现 这里采用ajax实现&#xff0c;需要添加Jquery依赖&#xff0c;然后在UserListView.vue中引入 在UserListView.vue组件的入口函数中定义users变量&#xff0c;并引入ref 使用ajax从云端动…