设计模式十二:享元模式(Flyweight Pattern)
当我们需要创建大量相似对象时,享元模式可以帮助我们节省内存空间和提高性能。该模式通过共享相同的数据来减少对象的数量。
在享元模式中,有两种类型的对象:享元(Flyweight)和非享元(Unshared Flyweight)。享元对象是可共享的,它包含内部状态和外部状态。内部状态是不变的,它可以在多个对象之间共享。外部状态是会变化的,它由客户端代码传递给享元对象,因此它不能被共享。
享元模式的核心思想是将相同的外部状态提取出来作为共享对象,在使用时通过传递外部状态进行对象的定制。这样就可以避免创建大量相同的对象,从而减少内存占用。
享元模式的适用场景
享元模式适用于需要创建大量相似对象,并希望节省内存空间和提高性能的场景。它通过共享相同的状态来减少对象的数量,以达到优化性能的目的。
- 当一个类有大量的相似对象,且这些对象可以共享一些相同的状态时,可以考虑使用享元模式。通过共享相同的状态,可以减少对象的数量,节省内存空间。
- 当大量对象导致内存占用过高,而且这些对象的状态可以被外部化时,可以使用享元模式来共享这些外部状态。外部状态可以由客户端代码传递给享元对象,从而避免创建大量重复的对象。
- 当需要在多个对象之间共享和复用状态时,可以使用享元模式。通过共享状态,可以实现对象的复用,提高性能。
- 当对象的数量很大,但每个对象只包含少量的状态时,可以考虑使用享元模式。通过共享状态,可以减少对象的数量,降低系统的复杂性和维护成本。
- 当希望将对象的内部状态和外部状态分离,并通过外部状态对对象进行定制时,可以使用享元模式。内部状态是不变的,可以在多个对象之间共享,而外部状态会变化,可以通过客户端代码传递给享元对象。
享元模式主要包含以下几个角色:
在享元模式中,具体享元对象之间可以共享内部状态,而外部状态是可变的,由客户端代码传递。享元工厂负责管理和创建享元对象,避免重复创建相同的享元对象。客户端通过享元工厂获取享元对象,并根据需要传入外部状态,从而定制享元对象的行为。这样可以在节省内存空间的同时,实现定制化的复用。
- 享元(Flyweight):它是一个接口或抽象类,定义了具体享元对象的共享方法和获取外部状态方法。
- 具体享元(Concrete Flyweight):实现了享元接口,包含内部状态和外部状态两部分。内部状态是不变的,可以被多个享元对象共享;外部状态是可变的,需要在使用时传入。
- 享元工厂(Flyweight Factory):管理和创建享元对象,通过一个数据结构(如哈希表)存储已经创建的享元对象,并根据需要进行复用或创建新的享元对象。
- 客户端(Client):通过享元工厂来获取享元对象,并根据需要传入外部状态。客户端可以通过共享享元对象的内部状态来节省内存空间和提高性能。
享元模式具体实现
以下实例通过创建歌曲享元工厂,实现歌曲的播放
享元接口
public interface Song {void play();
}
具体享元
/*** 国风歌曲*/
public class ChineseSong implements Song {private String songName;public ChineseSong(String songName) {this.songName = songName;}@Overridepublic void play() {System.out.println("A song called" + songName + " was played");}}
享元工厂
/*** 享元工厂类*/
public class FlyweightFactory {//定义一个集合,用于共享里面的对象private static Map<String, Song> songMap = new HashMap<>();public static ChineseSong getSong(String songName) {ChineseSong chineseSong = (ChineseSong) songMap.get(songName);if (chineseSong == null) {chineseSong = new ChineseSong(songName);songMap.put(songName, chineseSong);System.out.println("Add a new ChineseSong with : " + songName);}return chineseSong;}}
客户端
/*** 享元模式* 利用享元模式实现播放歌曲*/
public class Flyweight {public static void main(String[] args) {Song 稻香 = FlyweightFactory.getSong("稻香");稻香.play();Song 花田错 = FlyweightFactory.getSong("花田错");花田错.play();Song 稻香2 = FlyweightFactory.getSong("稻香");稻香2.play();}}
运行结果
Add a new ChineseSong with : 稻香
A song called稻香 was played
Add a new ChineseSong with : 花田错
A song called花田错 was played
A song called稻香 was played
在 FlyweightFactory中,使用了一个哈希表 Map 来存储已经创建的 Song对象。在获取 Song对象时,首先检查 Map 中是否已存在该颜色的对象,如果存在则直接返回,如果不存在则创建一个新的 Song对象,并将其加入到 Map 中。
享元模式的优缺点
享元模式的优点:
- 减少内存使用:享元模式通过共享对象来减少内存使用,特别是当有大量相似对象需要创建时。通过共享对象,可以节省大量的内存空间。
- 提高性能:由于享元模式共享对象,避免了频繁地创建和销毁对象,从而提高了系统的性能。
- 简化复杂对象:享元模式可以将复杂对象拆分成多个简单的共享对象,使得对象的创建和管理更加简单。
享元模式的缺点:
- 共享对象的状态不可变:由于享元对象被多个客户端共享,因此其内部状态必须是不可变的。如果某个客户端修改了共享对象的状态,可能会影响其他客户端的操作。
- 对象共享可能增加复杂性:在实现享元模式时,需要对对象进行合理的划分和管理,这可能增加系统的复杂性。
- 不适用于所有情况:享元模式主要适用于有大量相似对象需要共享的场景。对于不需要共享对象或者对象之间差异较大的情况,使用享元模式可能并不适合。
享元模式在需要创建大量相似对象且需要节省内存的场景下具有很好的优势,但也需要注意其适用性和状态管理的复杂性。
相关文章:
设计模式十二:享元模式(Flyweight Pattern)
当我们需要创建大量相似对象时,享元模式可以帮助我们节省内存空间和提高性能。该模式通过共享相同的数据来减少对象的数量。 在享元模式中,有两种类型的对象:享元(Flyweight)和非享元(Unshared Flyweight&a…...
【LeetCode】88. 合并两个有序数组 - 双指针
这里写自定义目录标题 2023-8-7 22:35:41 88. 合并两个有序数组 双指针 2023-8-7 22:35:41 class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int last m n ;while(n > 0){if(m > 0 && nums2[n-1] > nums1[m-1]){nums1[las…...

HarmonyOS应用开发的新机遇与挑战
HarmonyOS 4已经于2023年8月4日在HDC2023大会上正式官宣。对广大HarmonyOS开发者而言,这次一次盛大的大会。截至目前,鸿蒙生态设备已达7亿台,HarmonyOS开发者人数超过220万。鸿蒙生态充满着新机遇,也必将带来新的挑战。 HarmonyO…...
Qt中qmake、构建、运行、清理的区别
Qt 中默认的执行顺序:qmake--- 编译 --- 运行。 一、qmake qmake: 根据之前项目指南创建的项目文件 .pro,并且运行 qmake [qmake xx.pro]生成调试 [build-ttt-***-Debug] 或者发布 [build-ttt-***-Release] 目录(这个是影子构建…...

【设计模式——学习笔记】23种设计模式——观察者模式Observer(原理讲解+应用场景介绍+案例介绍+Java代码实现)
文章目录 案例引入原始方案实现实现问题分析 介绍基础介绍登场角色 案例实现案例一类图实现分析 案例二类图实现 观察者模式在JDK源码的应用总结文章说明 案例引入 有一个天气预报项目,需求如下: 气象站可以将每天测量到的温度、湿度、气压等等以公告的…...
【奇葩瑞萨-004】RX系列单片机的GPIO初始化
RX系列单片机的GPIO初始化 与IO口相关的寄存器端口(PORT)寄存器端口功能控制(MPC)寄存器MPC.PmnFPS的设置过程MPC寄存器设置注意事项 端口Pmn的初始化不同端口模式下,PORT、MCP寄存器的配置顺序 感想:与STM…...

【Git】Git切换地址
如何切换git代码地址? 1、查看当前远程 url git remote -v执行命令后,可以看见当前有2个URL。 远程 URL 在一般情况下有两个,分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时…...
elementUI点击当前行更改当前行状态(数据更新DOM不更新问题解决)
<template slot-scope"{row,$index}" slot"menu"><el-button v-if"row.editable" type"text" size"small" click"changeStatus(row,$index)">编辑</el-button><el-button v-else type"…...
python爬取阿里巴巴商品页面数据api
以下是使用Python爬取商品页面的示例代码: import requests from bs4 import BeautifulSoup# 定义要爬取的商品链接 url https://www.alibaba.com/product-detail/High-Quality-Custom-Logo-Printing-Black_60802527914.html# 发送请求 response requests.get(ur…...

angular-mat-select 多选 实现按选择顺序排序
mat-select 正常情况下,多选后,已选项是按列表顺序进行排序,如果我想实现按照点击项目的顺序进行排序,我该如何做呢? [参考网址](Angular order of selected option in multiple mat-select - Stack Overflow) sortComparator是Angular Material中mat-select组件的一个属…...

爬虫010_列表高级_添加_append_extend_修改_查询_in_not int_删除_del_pop_remove---python工作笔记029
然后再来看列表操作 首先添加append方法 然后插入,坐标是要插入的下标,右边是插入的内容 看结果 1,2,3,4,5,6 然后这个extend,是逐个插入,放到后边 然后是修改,直接对下标赋值 看结果</...

微服务服务拆分和远程调用
一、服务架构比较 单体架构:简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统 分布式架构:松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目&#x…...
MySQL8.1源码安装与部署
官方文档 https://downloads.mysql.com/archives/community/https://dev.mysql.com/doc/refman/8.1/en/binary-installation.html官方文档源码安装步骤 # Preconfiguration setup $> groupadd mysql $> useradd -r -g mysql -s /bin/false mysql # Beginning of source-b…...
algebraic reconstruction technique(ART)
数值线性代数的Kaczmarz方法被Gordon,Bender,Herman引入至CT重建中,称为ART方法。 A x b Axb Axb A A A为 m n m\times n mn的稀疏矩阵。 A A A的元素 a i j a_{ij} aij表示像素 j j j对射线 i i i投影的贡献。 A A A的行向量 a i T a…...

oracle11g安装
oracle11g安装 安装环境 虚拟机版本:centos7.9 虚拟机ip:192.168.5.144 oracle版本:11g oracle安装包:p13390677_112040_Linux-x86-64_1of7.zip,p13390677_112040_Linux-x86-64_2of7.zip,p13390677_11204…...

网络防御(9)
.一、SSL工作过程是什么? SSL位于应用层和传输层之间,它能够为基于TCP等可靠连接的应用层协议提供安全性保证。SSL协议本身分为两层: 上层为SSL握手协议(SSL handshake protocol)、SSLpassword变化协议(S…...
Spring核心与设计思想
文章目录 Spring是什么?认识Spring IoC容器传统的开发图书管理系统设计可能导致的问题 使用IoC容器 Spring是什么? Spring是一个用于构建企业级应用程序的开源框架,它为Java开发者提供了一种简化和加速应用程序开发的方式。Spring框架提供了…...
【stream的使用】使用stream.filter过滤List对象
Stream初相识 概括讲,可以将Stream流操作分为3种类型: 创建Stream Stream中间处理 终止Steam 每个Stream管道操作类型都包含若干API方法,先列举下各个API方法的功能介绍。 开始管道 主要负责新建一个Stream流,或者基于现有的数组…...

Flink多流处理之connect拼接流
Flink中的拼接流connect的使用其实非常简单,就是leftStream.connect(rightStream)的方式,但是有一点我们需要清楚,使用connect后并不是将两个流给串联起来了,而是将左流和右流建立一个联系,作为一个大的流,并且这个大的流可以使用相同的逻辑处理leftStream和rightStream,也可以…...

对任意类型数都可以排序的函数:qsort函数
之前我们学习过冒泡排序: int main() {int arr[] { 9,7,8,6,5,4,3,2,1,0 };int sz sizeof(arr)/sizeof(arr[0]);int i 0;for (i 0; i < sz-1; i) {int j 0;for (j 0; j < sz-1-i; j) {if (arr[j] > arr[j 1]){int temp 0;temp arr[j];arr[j] ar…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...