设计模式: 结构型之享元模式(7)

享元模式概述

  • 享元模式(Flyweight Pattern)是一种用于优化性能的结构型设计模式,它通过共享对象来减少内存中对象的数量
  • 享元模式通常用于当系统中存在大量相同或相似对象时,通过共享这些对象的状态来减少内存消耗
  • 我们会充分利用类型系统的优势来确保内部分享状态和外部状态的有效区分

享元模式示例

// 定义享元接口,这里抽象出所有共享对象共有的内部状态属性
interface Flyweight {intrinsicState: string; // 内部状态,不可变,可以被共享operation(exteriorState: any): void; // 外部状态作为方法参数传入
}// 具体享元类,实现了Flyweight接口
class ConcreteFlyweight implements Flyweight {constructor(private readonly uniqueId: number) {this.intrinsicState = `Internal state for object ${uniqueId}`;}getIntrinsicState(): string {return this.intrinsicState;}operation(exteriorState: any): void {console.log(`Executing operation with internal state: ${this.intrinsicState} and external state: ${exteriorState}`);}
}// 享元工厂类,负责创建并管理享元对象
class FlyweightFactory {private flyweights: Map<string | number, Flyweight> = new Map();getFlyweight(uniqueId: number): Flyweight {let flyweight = this.flyweights.get(uniqueId);if (!flyweight) {flyweight = new ConcreteFlyweight(uniqueId);this.flyweights.set(uniqueId, flyweight);}return flyweight;}
}// 使用示例
const factory = new FlyweightFactory();const context1 = 1;
const context2 = 2;const flyweight1 = factory.getFlyweight(context1);
const flyweight2 = factory.getFlyweight(context2);// 当上下文状态不同但内部状态相同的对象请求时,会复用已存在的享元对象
flyweight1.operation("External state A");
flyweight2.operation("External state B");// 如果context1再次请求,不会新建对象
const flyweight3 = factory.getFlyweight(context1);
flyweight3.operation("External state C");console.log(flyweight1 === flyweight3); // 输出:true,证明指向同一享元对象
  • 这个使用Typescript来实现的示例
  • 在这个例子中,ConcreteFlyweight 类代表具体的享元对象
  • 它包含了内部状态(在这里是唯一标识符)
  • Flyweight 接口定义了享元对象的操作方法,其中外部状态作为参数传递
  • FlyweightFactory 类作为一个工厂,它维护了一个享元对象的缓存池(Map)
  • 当请求一个新对象时,如果该内部状态的对象已经存在,则直接返回现有对象,否则创建新的对象并加入缓存池中
  • 这样,对于具有相同内部状态的不同外部状态请求,系统能够有效降低对象的数量,从而节约内存和提高性能

享元模式的应用场景

  • 享元模式是一种结构型设计模式,主要用于减少内存中对象的数量,从而优化系统性能。它通过共享对象的状态来实现这一目标
  • 以下是享元模式的主要应用场景

1 )系统中存在大量相似对象

  • 当系统中存在大量相似对象,且这些对象的某些部分状态可以共享时,可以使用享元模式
  • 通过共享这些状态,可以大幅度减少需要创建的对象数量,避免大量相似对象的开销,从而提高系统资源的利用率
  • 例如,在游戏开发中,棋子、角色等对象常常具有相似的属性和状态,使用享元模式可以有效地减少内存占用并提高性能

2 )对象的创建和销毁成本较高

  • 如果对象的创建和销毁需要消耗大量的资源,或者对象的初始化过程非常复杂,那么使用享元模式可以减少资源的消耗
  • 通过复用已有的对象,可以避免频繁地创建和销毁对象,从而降低系统的开销

3 )状态可以分为内部状态和外部状态

  • 享元模式要求将对象的状态分为内部状态和外部状态
  • 内部状态是对象不可变的共享部分,而外部状态是可以改变的独立部分
  • 当多个客户端请求同一个享元对象时,它们实际上共享的是同一个对象的内部状态,而外部状态则可以根据需要进行调整
  • 这种分离使得对象的复用更加灵活和高效

4 )需要精细控制对象共享

  • 在某些情况下,需要对对象的共享进行精细化控制
  • 通过享元工厂来管理享元对象的创建和共享,可以确保对象的共享是有序和可控的
  • 享元工厂可以维护一个对象池,根据需要提供共享对象,避免无限制地创建新对象

5 ) 其他

  • 除了上述场景外,享元模式还常常应用于系统底层的开发,如数据库连接池、字符串池等
  • 在这些场景中,通过复用已有的连接或字符串对象,可以减少资源的消耗并提高系统的性能

6 )总结

  • 总的来说,享元模式适用于那些需要优化内存使用、减少对象创建和销毁成本、以及需要精细控制对象共享的场景
  • 通过共享对象状态,享元模式可以有效地提高系统的性能和资源利用率
  • 但需要注意的是,享元模式可能会增加代码的复杂性,因此在应用时需要权衡其优缺点,并根据具体需求进行决策

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Armv7-M Interworking机制

1 前言 由于历史原因(从ARM7TDMI开始)&#xff0c; ARM处理器一直支持两种形式上相对独立的指令集&#xff0c; 它们分别是&#xff1a;  32位的ARM指令集&#xff0c;对应处理器状态&#xff1a; ARM状态&#xff0c;在32位存储器上效率较高&#xff0c;能够同时访问32位的数…

【PDF.js】PDF文件预览

【PDF.js】PDF文件预览 一、PDF.js二、PDF.js 下载1、下载PDF.js2、在项目中引入3、屏蔽跨域错误 三、项目中使用四、说明五、实现效果 使用PDFJS实现pdf文件的预览&#xff0c;支持预览指定页、关键词搜索、缩略图、页面尺寸调整等等。 一、PDF.js 官方地址 文档地址 二、PD…

FPGA开源项目分享——基于 DE1-SOC 的 String Art 实现

导语 今天继续康奈尔大学FPGA课程ECE 5760的典型案例分享——基于DE1-SOC的String Art实现。 &#xff08;更多其他案例请参考网站&#xff1a; Final Projects ECE 5760&#xff09; 1. 项目概述 项目网址 ECE 5760 Final Project 项目说明 String Art起源于19世纪的数学…

高精度地图导航论文汇总

文章目录 2022基于高精度地图的智能车辆路径规划与跟踪控制研究[M] 2023一种无人驾驶融合决策方案的设计与实现[M] 2022 基于高精度地图的智能车辆路径规划与跟踪控制研究[M] 摘要&#xff1a; 随着计算机及通信技术的不断进步&#xff0c;汽车行业也得到了飞速的发展。汽车在…

InternVideo2重塑视频理解新标杆,多模态学习引领行业风向

引言&#xff1a;视频理解的新篇章——InternVideo2的介绍 随着视频内容在日常生活中的普及&#xff0c;视频理解技术的重要性日益凸显。视频不仅包含丰富的视觉信息&#xff0c;还蕴含着动态变化和多模态元素&#xff0c;如音频和文本。这些特性使得视频成为一个复杂的数据类型…

LeetCode Meditations:合并 K 排序列表

描述 合并K分类列表 状态&#xff1a; 您有一系列 k 链接-列表 lists &#xff0c;每个链接-列表按升序排序。 合并所有链接-列表为一个排序的链接-列出并返回。 例如&#xff1a; Input: lists [[1, 4, 5], [1, 3, 4], [2, 6]] Output: [1, 1, 2, 3, 4, 4, 5, 6] Explanatio…

4.5 文字绘制

PutText 函数在图像中呈现指定的文本字符串。不能使用指定字体呈现的符号将由问号替换。 void cv::putText ( cv::Mat & img,//待绘制的图像 const String & text,//待绘制的文字 Point org,//文本框的左下角 int fontFace,//字体类型 double fontScale,//尺寸因…

虹科Pico汽车示波器 | 免拆诊断案例 | 2011款东风悦达起亚K5车发动机偶尔起动困难

一、故障现象 一辆2011款东风悦达起亚K5车&#xff0c;搭载G4KD发动机&#xff0c;累计行驶里程约为24.5万km。车主反映&#xff0c;第1次起动发动机时偶尔无法起动着机&#xff0c;第2次能够正常起动着机&#xff0c;但发动机故障灯异常点亮。为此在其他维修厂维修过&#xf…

网站HTTP升级成为HTTPS的方法

将网站从HTTP免费升级为HTTPS&#xff0c;您可以按照以下步骤操作&#xff1a; 1. 选择证书颁发机构&#xff08;CA&#xff09;&#xff1a; - 为了免费升级&#xff0c;您可以选择使用JoySSL这样的公益项目。JoySSL提供免费、自动化的SSL/TLS证书颁发服务&#xff0c;适用于各…

【Spring高级】SpringMVC处理流程总结

请求处理流程中&#xff0c;DispatcherServlet作为核心组件&#xff0c;负责控制整个流程&#xff0c;协调各个组件之间的交互。同时&#xff0c;SpringMVC提供了丰富的配置选项和扩展点&#xff0c;使得开发者可以根据具体需求定制和扩展功能。 当浏览器发送一个请求 http://…

【linux】yum 和 vim

yum 和 vim 1. Linux 软件包管理器 yum1.1 什么是软件包1.2 查看软件包1.3 如何安装软件1.4 如何卸载软件1.5 关于 rzsz 2. Linux编辑器-vim使用2.1 vim的基本概念2.2 vim的基本操作2.3 vim命令模式命令集2.4 vim底行模式命令集2.5 vim操作总结补充&#xff1a;vim下批量化注释…

MySQL 8.0 克隆(clone)插件快速搭建主从复制

MySQL 8.0 clone插件提供从一个实例克隆数据的功能&#xff0c;克隆功能提供了更有效的方式来快速创建MySQL实例&#xff0c;搭建主从复制和组复制。本文介绍使用 MySQL 8.0 clone 插件快速搭建主从复制的方法 环境&#xff1a; mysql 8.0.29 主库&#xff1a;192.168.56.201…

FFmpeg: 简易ijkplayer播放器实现--01项目简介

文章目录 项目介绍流程图播放器实现过程界面展示 项目介绍 此项目基于FFmeg中 ffplay.c进行二次开发&#xff0c;实现基本的功能&#xff0c;开发软件为Qt 项目优势&#xff1a; 参考ijkplayer播放器&#xff0c;实现UI界面和播放器核心进行解耦&#xff0c;容易添加其他功能…

【Kaggle比赛】DFL 德甲足球事件检测大赛(CV·目标检测-视频分类)

赛题解析 比赛目标 进球了!在这场比赛中,你会发现足球(足球)传球ーー包括掷界外球和传中球ーー以及德甲比赛中的挑战。您将开发一个计算机视觉模型,可以在长视频记录中自动分类这些事件。 您的工作将有助于规模的数据收集过程。自动事件注释可以使事件数据从目前未探索的…

解锁视觉密码:计算机视觉理论与应用

一、引言 A. 计算机视觉的定义与重要性 计算机视觉是一门研究如何使计算机能够“看”和理解图像或视频的科学。它结合了图像处理、模式识别、机器学习等多个领域的技术&#xff0c;旨在赋予计算机对视觉信息的感知、分析和理解能力。计算机视觉的重要性在于其能够模拟人眼的视…

ELK企业日志分析系统介绍

前言 随着企业级应用系统日益复杂&#xff0c;随之产生的海量日志数据。传统的日志管理和分析手段&#xff0c;难以做到高效检索、实时监控以及深度挖掘潜在价值。在此背景下&#xff0c;ELK日志分析系统应运而生。本文将从ELK 日志分析系统的原理、架构及其在实践中的应用做相…

使用Django开发爬虫系统

在本文中&#xff0c;我们将介绍如何使用Django开发一个简单但功能强大的爬虫系统。我们将使用Python编写爬虫&#xff0c;并将爬取到的数据存储到Django模型中&#xff0c;然后通过Django的管理页面管理这些数据。 1. 介绍 爬虫系统用于从互联网上收集信息&#xff0c;常用于…

Gin环境搭建详解

Gin环境搭建详解&#xff1a; 要安装Gin软件包&#xff0c;需要先安装Go并设置Go工作区。Gin环境搭建步骤如下&#xff1a; 【Gin框架】Gin环境搭建 Gin程序的热加载 Gin路由 GET POST PUT DELETE 1. 下载并安装 gin &#xff1a; $ go get -u github.com/gin-gonic/gin 2. …

Centos7下docker的jenkins下载并配置jdk与maven【图文教程】

个人记录 进入目录 cd /usr/local/JDK下载与配置 OpenJDK官网 下载安装 wget https://download.java.net/openjdk/jdk18/ri/openjdk-1836_linux-x64_bin.tar.gz解压 tar -zxvf openjdk-1836_linux-x64_bin.tar.gz ls ls jdk-18/编辑配置文件 vim /etc/profile配置环境变…

elementui树形组件自定义高亮颜色

1、需求描述&#xff1a;点击按钮切换树形的章节&#xff0c;同时高亮 2、代码实现 1&#xff09;style样式添加 <style> .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {background-color: #81d3f8 !important; //高亮颜色colo…