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

设计模式--享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享大量细粒度的对象来减少内存消耗。这个模式的核心思想是把对象的状态分为内在状态和外在状态,其中内在状态是可以共享的,而外在状态是需要独立维护的。

享元模式的结构

享元模式主要包含以下几个部分:

  1. 享元接口(Flyweight Interface):定义了具体享元类需要实现的方法。这些方法主要用于操作享元对象的内在状态。

  2. 具体享元类(Concrete Flyweight):实现享元接口,并存储可以共享的内在状态。

  3. 非共享享元类(Unshared Flyweight):并不是所有的享元对象都可以共享,对于那些不能共享的享元对象,可以通过这个类来实现。

  4. 享元工厂类(Flyweight Factory):负责创建和管理享元对象,并确保合理地共享这些对象。

  5. 客户端(Client):使用享元模式的类。客户端需要将外在状态传递给享元对象。

享元模式的实现

以下是一个简单的享元模式示例,用于管理和共享一些图形对象,如圆形。

// 享元接口
interface Shape {void draw(String color);
}// 具体享元类
class Circle implements Shape {private String intrinsicState; // 内在状态,可以共享private String extrinsicState; // 外在状态,每个对象独有public Circle(String intrinsicState) {this.intrinsicState = intrinsicState;}@Overridepublic void draw(String color) {this.extrinsicState = color;System.out.println("Drawing Circle with color: " + color + " and intrinsic state: " + intrinsicState);}
}// 享元工厂类
class ShapeFactory {private static final Map<String, Shape> circleMap = new HashMap<>();public static Shape getCircle(String intrinsicState) {Circle circle = (Circle) circleMap.get(intrinsicState);if (circle == null) {circle = new Circle(intrinsicState);circleMap.put(intrinsicState, circle);System.out.println("Creating circle with intrinsic state: " + intrinsicState);}return circle;}
}// 客户端
public class FlyweightPatternDemo {public static void main(String[] args) {Shape circle1 = ShapeFactory.getCircle("Shared State 1");circle1.draw("Red");Shape circle2 = ShapeFactory.getCircle("Shared State 1");circle2.draw("Green");Shape circle3 = ShapeFactory.getCircle("Shared State 2");circle3.draw("Blue");}
}

在这个示例中,Circle 类实现了 Shape 接口,并包含了内在状态(intrinsicState)和外在状态(extrinsicState)。ShapeFactory 类通过管理一个 HashMap 来共享 Circle 对象。客户端通过 ShapeFactory 获取 Circle 对象,并传递外在状态来绘制图形。

对象的状态分为内在状态和外在状态

将对象的状态分为内在状态和外在状态是享元模式的核心概念之一。内在状态是对象内部固有的、不随环境改变的状态,而外在状态是依赖于环境、可以在对象外部改变的状态。

为了更好地理解这个概念,我们可以通过一个例子来解释。

示例:围棋棋子

假设我们要实现一个围棋游戏,其中有许多棋子。这些棋子只有黑白两种颜色,但每个棋子的位置(行和列)是不同的。我们可以通过享元模式来共享棋子的颜色(内在状态),而位置(外在状态)则由客户端提供。

// 享元接口
interface GoPiece {void place(int row, int col);
}// 具体享元类
class GoPieceImpl implements GoPiece {private String color; // 内在状态public GoPieceImpl(String color) {this.color = color;}@Overridepublic void place(int row, int col) {System.out.println("Placing " + color + " piece at (" + row + ", " + col + ")");}
}// 享元工厂类
class GoPieceFactory {private static final Map<String, GoPiece> pieces = new HashMap<>();public static GoPiece getGoPiece(String color) {GoPiece piece = pieces.get(color);if (piece == null) {piece = new GoPieceImpl(color);pieces.put(color, piece);System.out.println("Creating " + color + " piece.");}return piece;}
}// 客户端
public class FlyweightPatternDemo {public static void main(String[] args) {GoPiece blackPiece1 = GoPieceFactory.getGoPiece("Black");blackPiece1.place(1, 1);GoPiece blackPiece2 = GoPieceFactory.getGoPiece("Black");blackPiece2.place(2, 2);GoPiece whitePiece1 = GoPieceFactory.getGoPiece("White");whitePiece1.place(1, 2);GoPiece whitePiece2 = GoPieceFactory.getGoPiece("White");whitePiece2.place(2, 1);}
}

在这个示例中:

  1. 内在状态:棋子的颜色(color)是可以共享的,这个状态是固定的,不会因为棋子的位置而改变。因此,我们将颜色设为内在状态。
  2. 外在状态:棋子的行和列(rowcol)是随时变化的,这个状态取决于棋子在棋盘上的具体位置。因此,我们将位置设为外在状态,由客户端在使用棋子时传递。

在享元模式中,通过将内在状态和外在状态分离,我们可以显著减少内存消耗。在上述示例中,我们只创建了两个享元对象(黑棋子和白棋子),即使我们在不同位置放置了多个棋子,也只是复用这两个享元对象。

享元模式的优缺点

优点

  1. 减少内存消耗:通过共享细粒度对象,可以显著减少内存使用,适用于大量重复对象的场景。
  2. 提高性能:由于减少了对象的创建和销毁,可以提高系统的性能。

缺点

  1. 复杂性增加:引入享元模式后,系统的复杂性增加,需要额外的代码来管理共享对象。
  2. 适用场景有限:享元模式并不适用于所有场景,只有在有大量细粒度对象需要共享时才适用。

适用场景

享元模式主要适用于以下场景:

  1. 系统中有大量相似对象,造成了内存的高消耗。
  2. 大部分对象的状态是可以外部化的,可以通过外在状态来区分对象。
  3. 对象的内在状态是相对稳定且不变的。

通过享元模式,可以在保证系统性能的前提下,有效地减少内存的使用,提高系统的可扩展性。

相关文章:

设计模式--享元模式

享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过共享大量细粒度的对象来减少内存消耗。这个模式的核心思想是把对象的状态分为内在状态和外在状态&#xff0c;其中内在状态是可以共享的&#xff0c;而外在状态是需要独立维护的。 享…...

可视化剪辑,账号矩阵,视频分发,聚合私信一体化营销工具 源----代码开发部署方案

可视化剪辑&#xff1a; 为了实现可视化剪辑功能&#xff0c;可以使用流行的视频编辑软件或者开发自己的视频编辑工具。其中&#xff0c;通过设计用户友好的界面&#xff0c;用户可以简单地拖拽和放大缩小视频片段&#xff0c;剪辑出满足需求的视频。在开发过程中&#xff0c;可…...

CCF-CSP认证考试 202406-2 矩阵重塑(其二) 100分题解

更多 CSP 认证考试题目题解可以前往&#xff1a;CSP-CCF 认证考试真题题解 原题链接&#xff1a; 202406-2 矩阵重塑&#xff08;其二&#xff09; 时间限制&#xff1a; 1.0 秒 空间限制&#xff1a; 512 MiB 题目背景 矩阵转置操作是将矩阵的行和列交换的过程。在转置过程…...

初阶数据结构的实现1 顺序表和链表

顺序表和链表 1.线性表1.1顺序表1.1.1静态顺序表&#xff08;不去实现&#xff09;1.1.2动态顺序表1.1.2.1 定义程序目标1.1.2.2 设计程序1.1.2.3编写代码1.1.2.3测试和调试代码 1.1.2 顺序表的问题与思考 1.2链表1.2.1链表的概念及结构1.2.1.1 定义程序目标1.2.1.2 设计程序1.…...

破解反爬虫策略 /_guard/auto.js(一) 原理

背景 当用代码或者postman访问一个网站的时候&#xff0c;访问他的任何地址都会返回<script src"/_guard/auto.js"></script>&#xff0c;但是从浏览器中访问显示的页面是正常的&#xff0c;这种就是网站做了反爬虫策略。本文就是带大家来破解这种策略&…...

40.简易频率计(基于等精度测量法)(3)

&#xff08;1&#xff09;BCD8421码&#xff1a;十进制数字转换成BCD8421码的方法 补零&#xff1a;你需要显示多少位数字&#xff0c;就在前面补上四倍的位宽。比如你要显示一个十进制8位的数字&#xff0c;就在前面补上8*432个零。判断&#xff1a;判断补零部分显示的十进制…...

关于Centos停更yum无法使用的解决方案

最近在使用Centos7.9系统时候&#xff0c;发现yum仓库无法进行安装软件包了&#xff0c;官方说2024年6月30日进行停更&#xff0c;停更后无法提供对应的软件服务。 我在使用yum安装包的时候发现确实不能使用官方服务了&#xff1a; CentOS停更的影响 CentOS停止更新之后&#…...

插画感言:成都亚恒丰创教育科技有限公司

插画感言&#xff1a;笔触间的灵魂对话 在这个快节奏、高压力的时代&#xff0c;我们时常在寻找那些能够触动心灵、让灵魂得以片刻栖息的角落。而插画&#xff0c;这一融合了艺术与情感的独特形式&#xff0c;便如同一股清泉&#xff0c;缓缓流淌进每个人的心田&#xff0c;以…...

【算法】数组中的第K个最大元素

难度&#xff1a;中等 题目&#xff1a; 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题…...

Perl 语言的特点

Perl 语言入门学习可以涵盖多个方面&#xff0c;包括其特点、基本语法、高级特性以及学习资源和社区支持等。以下是一个详细的入门学习指南&#xff1a; 一、Perl 语言的特点 文本处理能力强&#xff1a;Perl 提供了丰富的字符串处理函数和正则表达式的支持&#xff0c;非常适…...

NLP教程:1 词袋模型和TFIDF模型

文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型&#xff1a; 词集模型&#xff1a;单词构成的集合&#xff0c;集合自然每个元素都只有一个&#xff0c;也即词集中的每个单词都只有一个。 词袋模型&#xff1a;在词集的基础上如果一个单词…...

【开源 Mac 工具推荐之 2】洛雪音乐(lx-music-desktop):免费良心的音乐平台

旧版文章&#xff1a;【macOS免费软件推荐】第6期&#xff1a;洛雪音乐 Note&#xff1a;本文在旧版文章的基础上&#xff0c;新更新展示了一些洛雪音乐的新功能&#xff0c;并且描述更为详细。 简介 洛雪音乐&#xff08;GitHub 名&#xff1a;lx-music-desktop &#xff09;…...

AMEYA360:思瑞浦推出汽车级理想二极管ORing控制器TPS65R01Q

聚焦高性能模拟芯片和嵌入式处理器的半导体供应商思瑞浦3PEAK(股票代码&#xff1a;688536)发布汽车级理想二极管ORing控制器TPS65R01Q。 TPS65R01Q拥有20mV正向调节功能&#xff0c;降低系统损耗。快速反向关断(Typ&#xff1a;0.39μs)&#xff0c;在电池反向和各种汽车电气瞬…...

简约的悬浮动态特效404单页源HTML码

源码介绍 简约的悬浮动态特效404单页源HTML码,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head><meta charset="utf-8&q…...

Golang 创建 Excel 文件

经常会遇到需要导出数据报表的需求&#xff0c;除了可以通过 encoding/csv 导出 CSV 以外&#xff0c;还可以使用 https://github.com/qax-os/excelize 导出 xlsx 等格式的 excel&#xff0c;下面封装了一个方法&#xff0c;支持多 sheet 的 excel 数据生成&#xff0c;导出按需…...

探索GitHub上的两个革命性开源项目

在数字世界中&#xff0c;总有一些项目能够以其创新性和实用性脱颖而出&#xff0c;吸引全球开发者的目光。今天&#xff0c;我们将深入探索GitHub上的两个令人惊叹的开源项目&#xff1a;Comic Translate和GPTPDF&#xff0c;它们不仅改变了我们处理信息的方式&#xff0c;还极…...

SpringBoot框架学习笔记(三):Lombok 和 Spring Initailizr

1 Lombok 1.1 Lombok 介绍 &#xff08;1&#xff09;Lombok 作用 简化JavaBean开发&#xff0c;可以使用Lombok的注解让代码更加简洁Java项目中&#xff0c;很多没有技术含量又必须存在的代码&#xff1a;POJO的getter/setter/toString&#xff1b;异常处理&#xff1b;I/O…...

【ASP.NET网站传值问题】“object”不包含“GetEnumerator”的公共定义,因此 foreach 语句不能作用于“object”类型的变量等

问题一&#xff1a;不允许遍历 原因&#xff1a;实体未强制转化 后端: ViewData["CateGroupList"] grouplist; 前端加上&#xff1a;var catelist ViewData["CateGroupList"] as List<Catelogue>; 这样就可以遍历catelist了 问题二&#xff1a…...

Stateflow中的状态转换表

状态转换表是表达顺序模态逻辑的另一种方式。不要在Stateflow图表中以图形方式绘制状态和转换&#xff0c;而是使用状态转换表以表格格式表示模态逻辑。 使用状态转换表的好处包括&#xff1a; 易于对类列车状态机进行建模&#xff0c;其中模态逻辑涉及从一个状态到其邻居的转换…...

结合Redis解决接口幂等性问题

结合Redis解决接口幂等性问题 引言正文收获 引言 该问题产生背景是根据需求描述&#xff0c;要求对已发布的课程能进行编辑修改&#xff0c;并且要求能进行回滚。 幂等性问题描述&#xff1a;对同一个接口并发请求产生的结果是不变的。 Get 请求以及 Delete 请求天然保证幂等…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...