当前位置: 首页 > news >正文

17 结构型模式-享元模式

1 享元模式介绍

在这里插入图片描述
在这里插入图片描述

2 享元模式原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 享元模式实现

抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性.

//* 抽象享元类
public abstract class Flyweight {public abstract void operation(String extrinsicState);
}

具体享元类
具体享元类中要将内部状态和外部状态分开处理,内部状态作为具体享元类的成员变量,而外部状态通过注入的方式添加到具体享元类中.

/*** 可共享的-具体享元类* 注意: 在具体享元类中,需要将内部状态和外部状态分开处理.**/
public class ConcreteFlyweight extends Flyweight{//内部状态 : inState作为一个成员变量,同一个享元对象的内部状态是一致的.private String inState;public ConcreteFlyweight(String inState) {this.inState = inState;}/*** 外部状态在使用的时候,通常是有外部设置,不保存在享元对象中,即使是同一个对象* @param state*/@Overridepublic void operation(String state) {System.out.println("=== 享元对象的内部状态: " + inState + ",外部状态: " + state );}
}

非共享享元类,不复用享元工厂内部状态,但是是抽象享元类的子类或实现类

/*** 非共享的具体享元类**/
public class UnsharedFlyweight  extends Flyweight{private String inState;public UnsharedFlyweight(String inState) {this.inState = inState;}@Overridepublic void operation(String state) {System.out.println("=== 使用不共享对象,内部状态: " + inState + ",外部状态: " + state );}
}

享元工厂类, 管理一个享元对象类的缓存池。它会存储享元对象之间需要传递的共有状态,比如,按照大写英文字母来作为状态标识,这种只在享元对象之间传递的方式就叫内部状态。同时,它还提供了一个通用方法getFlyweight(),主要通过内部状态标识来获取享元对象。

/*** 享元工厂类* 作用: 作为存储享元对象的享元池.用户获取享元对象时先从享元池中获取,有则返回,没有创建新的返回给用户,* 并且在享元池中保存**/
public class FlyweightFactory {//定义一个Map集合用于存储享元对象,实现享元池private Map<String,Flyweight> pool = new HashMap<>();//实现享元对象之间的状态传递public FlyweightFactory() {//添加对应的内部状态pool.put("A",new ConcreteFlyweight("A"));pool.put("B",new ConcreteFlyweight("B"));pool.put("C",new ConcreteFlyweight("C"));}//根据内部状态进行查找public Flyweight getFlyweight(String key){//对象是否存在if(pool.containsKey(key)){System.out.println("=== 享元池中存在,直接复用,key : " + key);return pool.get(key);}else{//如果对象不存在,就创建一个添加到享元池,然后返回System.out.println("=== 享元池中不存在,创建并复用,key: " + key);Flyweight fw = new ConcreteFlyweight(key);pool.put(key,fw);return  fw;}}
}
public class Client {public static void main(String[] args) {//获取工厂对象FlyweightFactory factory = new FlyweightFactory();//通过工厂对象获取共享的享元对象Flyweight a1 = factory.getFlyweight("A");a1.operation("a1ExState");Flyweight a2 = factory.getFlyweight("A");a2.operation("a2ExState");System.out.println(a1 == a2);//获取非共享的享元对象UnsharedFlyweight u1 = new UnsharedFlyweight("A");UnsharedFlyweight u2 = new UnsharedFlyweight("A");System.out.println(u1 == u2);}
}
4 享元模式应用实例

在这里插入图片描述
在这里插入图片描述

/*** 抽象享元类: 五子棋**/
public abstract class GobangFlyweight {public abstract String getColor();public void display(){System.out.println("棋子颜色: " + this.getColor());}
}
/*** 共享享元类-白色棋子**/
public class WriteGobang extends GobangFlyweight {@Overridepublic String getColor() {return "白色";}
}
/*** 共享享元类-黑色棋子**/
public class BlackGobang extends GobangFlyweight {@Overridepublic String getColor() {return "黑色";}
}
/*** 享元工厂类-生产五子棋棋子**/
public class GobangFactory {//享元池private static Map<String,GobangFlyweight> pool;//创建共享享元对象,设置对象的内部状态private GobangFactory() {pool = new HashMap<>();GobangFlyweight black = new BlackGobang(); //黑子GobangFlyweight write = new WriteGobang(); //白子pool.put("b",black);pool.put("w",write);}//获取唯一享元工厂对象的方法public static GobangFactory getInstance(){return SingletonHolder.INSTANCE;}//静态内部类private static class SingletonHolder{private static final GobangFactory INSTANCE = new GobangFactory();}//通过key获取集合中的享元对象public GobangFlyweight getGobang(String key){return pool.get(key);}}
public class Client {public static void main(String[] args) {GobangFactory instance = GobangFactory.getInstance();//获取3颗黑子GobangFlyweight b1 = instance.getGobang("b");GobangFlyweight b2 = instance.getGobang("b");GobangFlyweight b3 = instance.getGobang("b");System.out.println("判断黑子是否是同一对象: " + (b1 == b2));GobangFlyweight w1 = instance.getGobang("w");GobangFlyweight w2 = instance.getGobang("w");System.out.println("判断白子是否是同一对象: " + (w1 == w2));//显示棋子b1.display();b2.display();b3.display();w1.display();w2.display();}
}

在这里插入图片描述

5 享元模式总结

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关文章:

17 结构型模式-享元模式

1 享元模式介绍 2 享元模式原理 3 享元模式实现 抽象享元类可以是一个接口也可以是一个抽象类,作为所有享元类的公共父类, 主要作用是提高系统的可扩展性. //* 抽象享元类 public abstract class Flyweight {public abstract void operation(String extrinsicState); }具体享…...

创建Secret(手动)

和创建其他类型的 API 对象&#xff08;Pod、Deployment、StatefulSet、ConfigMap 等&#xff09;一样&#xff0c;您也可以先在 yaml 文件中定义好 Secret&#xff0c;然后通过 kubectl apply -f 命令创建。此时&#xff0c;您可以通过如下两种方式在 yaml 文件中定义 Secret&…...

基于PHP的线上购物商城,MySQL数据库,PHPstudy,原生PHP,前台用户+后台管理,完美运行,有一万五千字论文。

目录 演示视频 基本介绍 论文截图 功能结构 系统截图 演示视频 基本介绍 基于PHP的线上购物商城&#xff0c;MySQL数据库&#xff0c;PHPstudy&#xff0c;原生PHP&#xff0c;前台用户后台管理&#xff0c;完美运行&#xff0c;有一万五千字论文。 现如今,购物网站是商业…...

Lua 事件触发机制(注册,触发)

日常工作中经常会用到触发机制&#xff0c;这里就提供一个注册触发机制&#xff0c;在代码中在也不用专门去调用各个模块的接口&#xff1b;只需要触发即可&#xff0c;触发后会自动调用接口 直接上代码 local _EventHandle {}; _EventHandle.listenerHandleIndex 0 _EventH…...

c++ 并发与多线程(12)线程安全的单例模式-1

一、什么是线程安全 在拥有共享数据的多条数据并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。 二、如何保证线程安全 法1、给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用; 法2、让线…...

Python学习笔记--迭代

一、迭代 什么叫做迭代&#xff1f; 比如在 Java 中&#xff0c;我们通过 List 集合的下标来遍历 List 集合中的元素&#xff0c;在 Python 中&#xff0c;给定一个 list 或 tuple&#xff0c;我们可以通过 for 循环来遍历这个 list 或 tuple &#xff0c;这种遍历就是迭代。…...

idea免费插件分享

分享一些在开发中常用到的idea插件&#xff0c;都是一些我自己常用的&#xff0c;希望对各位程序员有帮助吧。 1、Chinese Language 汉化插件&#xff1a;中文语言包将为您的 IntelliJ IDEA, AppCode, CLion, DataGrip, GoLand, PyCharm, PhpStorm, RubyMine, WebStorm, 和Rid…...

Pytorch使用torch.utils.data.random_split拆分数据集,拆分后的数据集状况

对于这个API,我最开始的预想是从 猫1猫2猫3猫4狗1狗2狗3狗4 中分割出 猫1猫2狗4狗1 和 猫4猫3狗2狗3 ,但是打印结果和我预想的不一样 数据集文件的存放路径如下图 测试代码如下 import torch import torchvisiontransform torchvision.transforms.Compose([torchvision.tran…...

每日一练 | 华为认证真题练习Day122

1、路由器所有的接口属于同一个广播域。 A. 对 B. 错 2、下列配置默认路由的命令中&#xff0c;正确的是&#xff08;&#xff09;。 A. [Huawei]ip route-static 0.0.0.0 0.0.0.0 192.168.1.1 B. [Huawei-Serial0]ip route-static 0.0.0.0 0.0.0.0 0.0.0.0 C. [Huawei]ip…...

SQL sever中函数(2)

目录 一、函数分类及应用 1.1标量函数&#xff08;Scalar Functions&#xff09;&#xff1a; 1.1.1格式 1.1.2示例 1.1.3作用 1.2表值函数&#xff08;Table-Valued Functions&#xff09;&#xff1a; 1.2.1内联表值函数&#xff08;Inline Table-Valued Functions&am…...

win10专业版驱动开发

我使用的系统版本如何下&#xff1a; 使用的visual studio为VS2019,使用的SDK,WDK如下&#xff1a; 在visual studio单个组件里选择SDK10.0.018362.0 在WDK里面选择版本为&#xff1a; 下载链接如下&#xff1a; 以前的 WDK 版本和其他下载 - Windows drivers | Microsoft Le…...

【JavaEE】网络编程---TCP数据报套接字编程

一、TCP数据报套接字编程 1.1 ServerSocket API ServerSocket 是创建TCP服务端Socket的API ServerSocket 构造方法&#xff1a; ServerSocket 方法&#xff1a; 1.2 Socket API Socket 是客户端Socket&#xff0c;或服务端中接收到客户端建立连接&#xff08;accept方法&…...

用 Go 访问 MySql 数据库

所有代码样例 package mainimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql" )var db *sql.DB// 初始化连接 func initDB() (err error) {db, err sql.Open("mysql", "root:mm..1213tcp(127.0.0.1:3306)/chapte…...

mac 升级node到指定版本

node版本14.15.1升级到最新稳定版18.18.2 mac系统 先查看一下自己的node版本 node -v开始升级 第一步 清除node的缓存 sudo npm cache clean -f第二步 安装n模块【管理模块 n是管理 nodejs版本】 sudo npm install -g n第三步升级node sudo n stable // 把当前系统的 Node…...

欢迎进QQ群讨论交流

...

C语言解决八皇后问题

八皇后问题是指在一个88的棋盘上&#xff0c;放置8个皇后&#xff0c;使得任意两个皇后都不能在同一行、同一列或同一斜线上。这是一个著名的递归问题。下面是一个C语言实现八皇后问题的代码&#xff0c;以及对代码的讲解。 #include <stdio.h>int board[8][8] {0}; //…...

springboot集成canal,将数据发送至接口

前置条件&#xff1a; mysql开启binlog日志部署canal服务 Springboot代码&#xff1a; 接口工具类&#xff1a; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; imp…...

Selenum八种常用定位(案例解析)

Selenium是一个备受推崇的工具。它有着丰富的功能&#xff0c;让我们能够与网页互动&#xff0c;执行各种任务&#xff0c;能为测试工程师和开发人员提供了很大的便利。 要充分利用Selenium&#xff0c;就需要了解如何正确定位网页上的元素。 接下来我将带大家共同探讨Seleni…...

Web前端接入Microsoft Azure AI文本翻译

Azure 文本翻译是 Azure AI 翻译服务的一项基于云的 REST API 功能。 文本翻译 API 支持实时快速准确地进行源到目标文本翻译。 文本翻译软件开发工具包 (SDK) 是一组库和工具&#xff0c;可用于轻松地将文本翻译 REST API 功能集成到应用程序中。 文本翻译 SDK 可跨 C#/.NET、…...

容联七陌助力鱼跃医疗升级智能联络中心,让客户服务更“鱼跃”

在当今高度竞争的市场环境中&#xff0c;企业的客户服务质量对于维护品牌形象和保持竞争优势至关重要。而随着人工智能、大数据等技术快速发展&#xff0c;智能化客户服务正在成为各行各业发展的重要部分。 鱼跃医疗是一家致力于“用科技律动生命"的国内知名医疗制造企业…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...