设计模式使用场景实现示例及优缺点(结构型模式——享元模式)
结构型模式
享元模式(Flyweight Pattern)
享元模式,作为软件设计模式中的一员,其核心目标在于通过共享来有效地支持大量细粒度对象的使用。在内存使用优化方面,享元模式提供了一种极为高效的路径,尤其在处理大量对象且这些对象中多数属性相同的情况下表现得尤为突出。
享元模式的基本概念与应用
享元模式基于一个简单的理念:分离变与不变,共享不变,独立变化。具体到实现上,享元模式通常涉及到两个主要的组成部分——享元对象和享元工厂。享元对象中包含的状态可以分为内部状态和外部状态,其中内部状态是可以共享的不变状态,而外部状态则由具体的使用场景决定,不能共享。
内部状态(Intrinsic State):如字符代码的字体、大小等属性,这些属性对于同种类型的对象来说是共有的。
外部状态(Extrinsic State):如字符在文档中的位置,这些状态根据具体的使用场景会有所不同。
使用享元模式的典型场景包括处理大量相似对象时,这些对象由于其数量或复杂度会消耗大量内存资源。例如,在文本编辑器中,每个字符可以是一个对象;而字符的字体、大小可以是内部状态,字符的位置和颜色可以是外部状态。
适用场景
-
大量对象:
- 当应用程序使用了大量的对象,且这些对象因为数量巨大而造成很高的内存开销时。
-
可重复使用对象的状态:
- 对象的大多数状态都可以变为外部状态,也就是说,对象状态可以由其使用的上下文来决定。
-
细粒度对象:
- 应用程序不依赖于对象身份。由于享元对象可以被共享,对于概念上明显有别的对象,标识测试会返回真。
结构
享元模式包含以下几个核心角色:
享元工厂(Flyweight Factory):
负责创建和管理享元对象,通常包含一个池(缓存)用于存储和复用已经创建的享元对象。
具体享元(Concrete Flyweight):
实现了抽象享元接口,包含了内部状态和外部状态。内部状态是可以被共享的,而外部状态则由客户端传递。
抽象享元(Flyweight):
定义了具体享元和非共享享元的接口,通常包含了设置外部状态的方法。
客户端(Client):
使用享元工厂获取享元对象,并通过设置外部状态来操作享元对象。客户端通常不需要关心享元对象的具体实现。
实现示例(Java)
以下是一个简单的享元模式的实现示例,展示如何利用共享技术来管理字符的实例。
1. 定义享元接口
public interface Flyweight {void operation(String extrinsicState);
}
2. 创建具体享元类
public class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("Intrinsic State = " + intrinsicState + ", Extrinsic State = " + extrinsicState);}
}
3. 创建享元工厂类
import java.util.HashMap;
import java.util.Map;public class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}
4. 客户端代码
public class Client {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweightA = factory.getFlyweight("A");Flyweight flyweightB = factory.getFlyweight("B");Flyweight flyweightA2 = factory.getFlyweight("A");flyweightA.operation("First Call");flyweightB.operation("Second Call");flyweightA2.operation("Third Call");}
}
优点
-
减少对象的创建:
- 享元模式可以极大地减少系统中对象的数量,降低系统内存的消耗,提高效率。
-
外部状态独立:
- 外部状态相对独立,不影响内部状态,使得享元对象可以在不同的环境中被共享。
缺点
-
复杂性增加:
- 使系统设计更加复杂,需要将对象的状态外部化,分离内部和外部状态,使得程序的逻辑复杂化。
-
线程安全问题:
- 在多线程环境下,共享的享元对象可能会引起线程安全问题,需要进行适当的同步处理。
类图
Client|v
FlyweightFactory ----> Flyweight <---- ConcreteFlyweight
总结
享元模式是一种结构型设计模式,它通过共享技术有效地支持大量细粒度对象的使用,适用于那些需要优化内存使用且对象数量巨大的系统。通过合理的使用享元模式,开发者可以在性能和资源利用之间找到一个良好的平衡点。然而,设计和实现享元模式需要仔细考虑如何分离内部状态和外部状态,确保系统的高效运行同时,也要注意不增加过多的运行时负担。
相关文章:

设计模式使用场景实现示例及优缺点(结构型模式——享元模式)
结构型模式 享元模式(Flyweight Pattern) 享元模式,作为软件设计模式中的一员,其核心目标在于通过共享来有效地支持大量细粒度对象的使用。在内存使用优化方面,享元模式提供了一种极为高效的路径,尤其在处…...

开放式耳机哪款比较好?五款开放式耳机测评推荐
开放式耳机真的越来越火了,真的好多人问我,开放式耳机应该怎么选啊,所以这次我亲自测评了几款开放式耳机,作为数码博主这一篇文章就教大家如何挑选开放式耳机,当然最后还有五款开放式耳机的推荐给到大家,话…...

【网络安全】实验三(基于Windows部署CA)
一、配置环境 打开两台虚拟机,并参照下图,搭建网络拓扑环境,要求两台虚拟的IP地址要按照图中的标识进行设置,并根据搭建完成情况,勾选对应选项。注:此处的学号本人学号的最后两位数字,1学号100…...

hive中reverse函数
目录 前言基本函数介绍实战 前言 reverse函数,是一个常用的字符串处理函数,很多编程语言都有。最近开发中,遇到一个reverse解决的需求,发现自己尚未总结过,遂补上。 基本函数介绍 SELECT reverse(string_column) FR…...

SimpleTrack环境配置教程
SimpleTrack环境配置教程 conda create --name SimpleTrack python3.6 conda activate SimpleTrack git clone https://github.com/tusen-ai/SimpleTrack.git cd ./SimpleTrack/ # pip install opencv-python4.5.4.58 # 安装opencv-python报错,可尝试安此版本 pip …...

frameworks 之Zygote
frameworks 之Zygote Zygote.rc 解析Zygote 启动ZygoteInit.javaZygote.cppLiunx fork Zygote 中文意思为受精卵。 和其意思一样,该功能负责android系统孵化service 和 app 进程。 本文讲解Zygote的大概流程。涉及的相同的类,如下所示 system/core/rootd…...

基于考研题库小程序V2.0实现倒计时功能板块和超时判错功能
V2.0 需求沟通 需求分析 计时模块 3.1.1、功能描述←计时模块用于做题过程中对每一题的作答进行30秒倒计时,超时直接判错,同时将总用时显示在界面上;记录每次做题的总用时。 3.1.2、接口描述←与判定模块的接口为超时判定,若单题用时超过 …...

idm站点抓取可以用来做什么 idm站点抓取能抓取本地网页吗 idm站点抓取怎么用 网络下载加速器
在下载工具众多且竞争激烈的市场中,Internet Download Manager(简称IDM)作为一款专业的下载加速软件,仍然能够赢得众多用户的青睐,这都要得益于它的强大的下载功能。我们在开始使用IDM的时候总是有很多疑问,…...

maven7——(重要,构建项目)maven项目构建(命令)
Maven的常用命令管理项目的生命周期 clean命令 清除编译产生的target文件夹内容,可以配合相应命令在cmd中使用,如mvn clean package, mvn clean test D:\工作\公司培训-4班\day20\day20\untitled1>mvn clean compile命令 该命令可以…...

容联云发布容犀大模型应用,重塑企业“营销服”|WAIC 2024
7月6日,在2024世界人工智能大会上,容联云成功举办主题为“数智聚合 产业向上”的生成式应用与大模型商业化实践论坛。 论坛上,容联云发布了容犀智能大模型应用升级,该系列应用包括容犀Agent Copilot、容犀Knowledge Copilot、容犀…...

Docker 安装字体文件
由于 Docker 容器的隔离性,与宿主机是独立的运行环境,如果需要用到宿主机的字体文件就需要进行安装。 例如在导出 PDF 文件时,如果缺少字体文件,就会产生乱码(常表现为中文变成方框)。 Docker 字体文件的安…...

C/C++ 移动追加内容到文件尾部。
1、通过C语言文件函数库 1.1、通过追加到尾部字符命令 FILE* f fopen(file_path.data(), "ab"); 1.2、不通过追加到尾部字符命令 FILE* f fopen(path, "rb"); if (NULL ! f) { fseek(f, 0, SEEK_END); } Unix 平台(Linux/Android/MacOS…...

ISO/OIS的七层模型②
OSI模型是一个分层的模型,每一个部分称为一层,每一层扮演固定的角色,互不干扰。OSI有7层,从上到下分别是: 一,每层功能 7.应用层(Application layer ):应用层功能&#x…...

美团到家平台业务探索
背景 到家业务发展已经近10年,目前最为火热的应该有美团到家、抖音到家等,这种极具挑战性的业务,值得学习和思考。 既然是服务平台化,那一定是兼容了多种业务以及多种模式。 挑战 订单、骑手规模大,供需匹配过程的…...

React -- useState状态更新异步特性——导致获取值为旧值的问题
useState状态异步更新 问题导致的原因解决办法进一步分析后续遇到的新问题 问题 const [isSelecting, setIsSelecting] useState(false);useEffect(() > {const handleKeyDown (event) > {if (event.key Escape) {if(isSelectingRef){//.......setIsSelecting(!isSele…...

哪款开放式耳机是2024年最值得购买的?五大品质好物揭秘
相比于入耳式耳机压耳、堵耳,佩戴不稳固等缺陷,开放式耳机的佩戴舒适性和安全性都更胜一筹,这几年成为了越来越多年轻人的“音乐搭子”。面对市面上各式各样的开放式耳机,相信大家在挑选上就得下大把功夫,选择上也有困…...

深圳天童美语:小暑习俗知多少
小暑已至,炎炎夏日正当时。在这个充满生机的节气里,除了我们熟悉的吃冰、游泳等消暑方式,还有许多有趣且富含文化内涵的小暑习俗。今天,深圳天童美语就带你一起解锁这些习俗,感受那份独特的夏日风情! …...

递归参数中递增运算符的使用
backtrack(k,n,sum,i1); backtrack(k,n,sum,i); 在 C 中,递增运算符 i 和表达式 i1 之间有显著的区别: i 是后置递增运算符,表示先使用 i 的当前值,然后将 i 加 1。i1 是一个简单的算术运算,返回 i 的当前值加 1&…...

Python功能制作之获取CSDN所有发布文章的对应数据
大家好,今天我要分享的是一个实用的Python脚本,它可以帮助你批量获取CSDN博客上所有发布文章的相关数据,并将这些数据保存到Excel文件中。此外,脚本还会为每篇文章获取一个质量分,并将这个分数也记录在Excel中。让我们…...

Backend - C# 基础知识
目录 一、程序结构 (一)内容 1. 命名空间声明 Namespace 2. 一个 class 类 3. class 方法(类方法) 4. class 属性 5. 一个 main 方法(程序入口) 6. 语句&表达式 7. 注释 (二)举例…...

HTML5新增的input元素类型:number、range、email、color、date等
HTML5 大幅度地增加与改良了 input 元素的种类,可以简单地使用这些元素来实现 HTML5 之前需要使用 JavaScript 才能实现的许多功能。 到目前为止,大部分浏览器都支持 input 元素的种类。对于不支持新增 input 元素的浏览器,input 元素被统一…...

00 Debian字符界面如何支持中文
作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian字符界面如何支持中文 《傅老师Debian知识库系列之00》——原创 前言 傅老师Debian知识库特点: 1、拆解Debian实用技能; 2、…...

以太网中的各种帧结构
帧结构(Ethernet Frame Structure)介绍 以太网信号帧结构(Ethernet Signal Frame Structure),有被称为以太网帧结构,一般可以分为两类 —— 数据帧和管理帧。 按照 IEEE 802.3,ISO/IEC8803-3 …...

C++入门基础题:数组元素逆序(C++版互换方式)
1.题目: 数组元素逆置案例描述: 请声明一个5个元素的数组,并且将元素逆置. (如原数组元素为:1,3,2,5,4;逆置后输出结果为:4,5,2,3,1) 2.图解思路: 3.代码演示: #include<iostream>using namespace std;int main(){int a…...

3款自己电脑就可以运行AI LLM的项目
AnythingLLM、LocalGPT和PrivateGPT都是与大语言模型(LLM)相关的项目,它们允许用户在本地环境中与文档进行交互,但它们在实现方式和特点上存在一些差异。AnythingLLM使用Pinecone和ChromaDB来处理矢量嵌入,并使用OpenA…...

各云厂商取消免费一年期SSL证书
目录 第一次削减SSL证书有效期: SSL证书单次签发有效期可能再次削减: 目前市场趋势显现: 各类削减政策意味着什么: 上有政策、下有对策—怎么实现超长SSL证书有效期: 如何申请全自动化部署的SSL证书:…...

自动化测试高级控件交互方法:TouchAction、触屏操作、点按,双击,滑动,手势解锁!
在自动化测试领域中,TouchAction 是一种非常强大的工具,它允许我们模拟用户在设备屏幕上的各种触摸事件。这种模拟不仅限于简单的点击操作,还包括滑动、长按、多点触控等复杂的手势。 点按与双击 点按和双击是触屏设备上最基本的操作之一。…...

leetcode165.解密数字
题目表述: 这道题目和斐波那契数列以及跳台阶问题十分相似。 斐波那契数列:0、1、1、2、3、5, 8、13、21、34 …… leetcode跳台阶问题:1、1、2、3、5, 8、13、21、34....... 这类题目的特点都是第N项的结果等于前两项的和。 但是解密数…...

对为什么react需要时间分片,vue3不需要的浅学习
1、时间分片 时间分片指在让应用在cpu进行大量计算时也能与用户交互,但时间分片只能对大量cpu计算进行优化,无法优化复杂DOM操作,因为要确保用户正在操作的界面是最新。 web卡顿的场景: 1、cpu计算量不大,但dom操作…...

电脑干货分享 · 删除资源管理器导航栏 OneDrive 及 3D 对象
Win10资源管理器的左侧导航栏默认有一个OneDrive的项,但由于微软龟速的原因,OneDrive在国内基本很少有人使用,我们动手给它KO了! 网上有很多这类的教程,但都是要手动修改注册表,对于小白来说,有…...