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 对象(Pod、Deployment、StatefulSet、ConfigMap 等)一样,您也可以先在 yaml 文件中定义好 Secret,然后通过 kubectl apply -f 命令创建。此时,您可以通过如下两种方式在 yaml 文件中定义 Secret&…...
基于PHP的线上购物商城,MySQL数据库,PHPstudy,原生PHP,前台用户+后台管理,完美运行,有一万五千字论文。
目录 演示视频 基本介绍 论文截图 功能结构 系统截图 演示视频 基本介绍 基于PHP的线上购物商城,MySQL数据库,PHPstudy,原生PHP,前台用户后台管理,完美运行,有一万五千字论文。 现如今,购物网站是商业…...
Lua 事件触发机制(注册,触发)
日常工作中经常会用到触发机制,这里就提供一个注册触发机制,在代码中在也不用专门去调用各个模块的接口;只需要触发即可,触发后会自动调用接口 直接上代码 local _EventHandle {}; _EventHandle.listenerHandleIndex 0 _EventH…...
c++ 并发与多线程(12)线程安全的单例模式-1
一、什么是线程安全 在拥有共享数据的多条数据并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。 二、如何保证线程安全 法1、给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用; 法2、让线…...
Python学习笔记--迭代
一、迭代 什么叫做迭代? 比如在 Java 中,我们通过 List 集合的下标来遍历 List 集合中的元素,在 Python 中,给定一个 list 或 tuple,我们可以通过 for 循环来遍历这个 list 或 tuple ,这种遍历就是迭代。…...
idea免费插件分享
分享一些在开发中常用到的idea插件,都是一些我自己常用的,希望对各位程序员有帮助吧。 1、Chinese Language 汉化插件:中文语言包将为您的 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、下列配置默认路由的命令中,正确的是()。 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标量函数(Scalar Functions): 1.1.1格式 1.1.2示例 1.1.3作用 1.2表值函数(Table-Valued Functions): 1.2.1内联表值函数(Inline Table-Valued Functions&am…...
win10专业版驱动开发
我使用的系统版本如何下: 使用的visual studio为VS2019,使用的SDK,WDK如下: 在visual studio单个组件里选择SDK10.0.018362.0 在WDK里面选择版本为: 下载链接如下: 以前的 WDK 版本和其他下载 - Windows drivers | Microsoft Le…...
【JavaEE】网络编程---TCP数据报套接字编程
一、TCP数据报套接字编程 1.1 ServerSocket API ServerSocket 是创建TCP服务端Socket的API ServerSocket 构造方法: ServerSocket 方法: 1.2 Socket API Socket 是客户端Socket,或服务端中接收到客户端建立连接(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的棋盘上,放置8个皇后,使得任意两个皇后都不能在同一行、同一列或同一斜线上。这是一个著名的递归问题。下面是一个C语言实现八皇后问题的代码,以及对代码的讲解。 #include <stdio.h>int board[8][8] {0}; //…...
springboot集成canal,将数据发送至接口
前置条件: mysql开启binlog日志部署canal服务 Springboot代码: 接口工具类: import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; imp…...
Selenum八种常用定位(案例解析)
Selenium是一个备受推崇的工具。它有着丰富的功能,让我们能够与网页互动,执行各种任务,能为测试工程师和开发人员提供了很大的便利。 要充分利用Selenium,就需要了解如何正确定位网页上的元素。 接下来我将带大家共同探讨Seleni…...
Web前端接入Microsoft Azure AI文本翻译
Azure 文本翻译是 Azure AI 翻译服务的一项基于云的 REST API 功能。 文本翻译 API 支持实时快速准确地进行源到目标文本翻译。 文本翻译软件开发工具包 (SDK) 是一组库和工具,可用于轻松地将文本翻译 REST API 功能集成到应用程序中。 文本翻译 SDK 可跨 C#/.NET、…...
容联七陌助力鱼跃医疗升级智能联络中心,让客户服务更“鱼跃”
在当今高度竞争的市场环境中,企业的客户服务质量对于维护品牌形象和保持竞争优势至关重要。而随着人工智能、大数据等技术快速发展,智能化客户服务正在成为各行各业发展的重要部分。 鱼跃医疗是一家致力于“用科技律动生命"的国内知名医疗制造企业…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
