设计模式使用场景实现示例及优缺点(结构型模式——享元模式)

国度的东南角,有一个被称为“享元村”的小村庄。村里的居民都是非常聪明的软件设计师,他们擅长用一种叫做“享元模式”的技术来解决内存使用问题。享元模式的核心思想是共享:通过共享来支持大量的细粒度对象的使用,从而在不牺牲程序性能的情况下,有效地减少内存的使用。

有一天,享元村的村长召集了所有村民,讲述了一个即将到来的挑战。“我们将接手一个非常大的项目,”村长说,“这个项目中有成千上万的用户和同样多的数据对象需要处理。我们必须找到一种方式来优化我们的程序,以便它能在不增加更多内存的情况下,高效地运行。”

所有的村民都聚在一起,开始讨论解决方案。他们决定利用享元模式,创建一个‘对象池’,这个池子里存放着所有可以共享的对象。每当程序需要一个新的对象时,它首先检查对象池中是否已经有一个相似的对象。如果有,程序就会重用这个对象;如果没有,它们才会创建一个新的对象并将其添加到池中。

结构型模式

享元模式(Flyweight Pattern)

享元模式,作为软件设计模式中的一员,其核心目标在于通过共享来有效地支持大量细粒度对象的使用。在内存使用优化方面,享元模式提供了一种极为高效的路径,尤其在处理大量对象且这些对象中多数属性相同的情况下表现得尤为突出。

享元模式的基本概念与应用

享元模式基于一个简单的理念:分离变与不变,共享不变,独立变化。具体到实现上,享元模式通常涉及到两个主要的组成部分——享元对象和享元工厂。享元对象中包含的状态可以分为内部状态和外部状态,其中内部状态是可以共享的不变状态,而外部状态则由具体的使用场景决定,不能共享。

内部状态(Intrinsic State):如字符代码的字体、大小等属性,这些属性对于同种类型的对象来说是共有的。

外部状态(Extrinsic State):如字符在文档中的位置,这些状态根据具体的使用场景会有所不同。

使用享元模式的典型场景包括处理大量相似对象时,这些对象由于其数量或复杂度会消耗大量内存资源。例如,在文本编辑器中,每个字符可以是一个对象;而字符的字体、大小可以是内部状态,字符的位置和颜色可以是外部状态。

适用场景

  1. 大量对象

    • 当应用程序使用了大量的对象,且这些对象因为数量巨大而造成很高的内存开销时。
  2. 可重复使用对象的状态

    • 对象的大多数状态都可以变为外部状态,也就是说,对象状态可以由其使用的上下文来决定。
  3. 细粒度对象

    • 应用程序不依赖于对象身份。由于享元对象可以被共享,对于概念上明显有别的对象,标识测试会返回真。

结构

享元模式包含以下几个核心角色:

享元工厂(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");}
}

优点

  1. 减少对象的创建

    • 享元模式可以极大地减少系统中对象的数量,降低系统内存的消耗,提高效率。
  2. 外部状态独立

    • 外部状态相对独立,不影响内部状态,使得享元对象可以在不同的环境中被共享。

缺点

  1. 复杂性增加

    • 使系统设计更加复杂,需要将对象的状态外部化,分离内部和外部状态,使得程序的逻辑复杂化。
  2. 线程安全问题

    • 在多线程环境下,共享的享元对象可能会引起线程安全问题,需要进行适当的同步处理。

类图

Client|v
FlyweightFactory ----> Flyweight <---- ConcreteFlyweight

总结

享元模式是一种结构型设计模式,它通过共享技术有效地支持大量细粒度对象的使用,适用于那些需要优化内存使用且对象数量巨大的系统。通过合理的使用享元模式,开发者可以在性能和资源利用之间找到一个良好的平衡点。然而,设计和实现享元模式需要仔细考虑如何分离内部状态和外部状态,确保系统的高效运行同时,也要注意不增加过多的运行时负担。

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

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

相关文章

C# 设计一个可变长度的数据通信协议编码和解码代码。

设计一个可变长度的数据通信协议编码和解码代码。 要有本机ID字段&#xff0c;远端设备ID字段&#xff0c;指令类型字段&#xff0c;数据体字段&#xff0c;校验字段。其中一个要求是&#xff0c;每次固定收发八个字节&#xff0c;单个数据帧超过八个字节需要分包收发。对接收的…

超详细信息收集篇

1 域名信息收集 1.1 域名是什么 域名&#xff08;英语&#xff1a;Domain Name&#xff09;&#xff0c;又称网域&#xff0c;是由一串用点分隔的名字组成的 Internet 上某一台 计算机 或计算机组的名称&#xff0c;用于在数据传输时对计算机的定位标识&#xff08;有时也指地…

数据结构——栈和队列(C语言实现)

写在前面&#xff1a; 栈和队列是两种重要的线性结构。其也属于线性表&#xff0c;只是操作受限&#xff0c;本节主要讨论的是栈和队列的定义、表示方法以及C语言实现。 一、栈和队列的定义与特点 栈&#xff1a;是限定仅在表尾进行插入和删除的线性表。对栈来说&#xff0c;表…

【经验分享】关于静态分析工具排查 Bug 的方法

文章目录 编译器的静态分析cppcheck安装 cppcheck运行 cppcheck 程序员的日常工作&#xff0c;不是摸鱼扯皮&#xff0c;就是在写 Bug。虽然这是一个梗&#xff0c;但也可以看出&#xff0c;程序员的日常一定绕不开 Bug。而花更少的时间修复软件中的 Bug&#xff0c;且不引入新…

C#自定义异常(Exception)的实现

1、自定义异常类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ExceptionApp {public class CustomException:Exception{//默认构造函数public CustomException():base() { }//接收错误信…

leetcode hot 100 刷题记录(medium)

题目3&#xff1a;无重复字符的最长子串&#xff08;YES&#xff09; 解题思路&#xff1a;其实最好想到的方法就是使用两层for,让每个字符都可以是子串的首字符&#xff0c;查看哪个子串的长度最长即可。 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子…

lightgbm

lightGBM 1.sklearn 使用代码 【机器学习基础】XGBoost、LightGBM与CatBoost算法对比与调参 首先&#xff0c;XGBoost、LightGBM和CatBoost都是目前经典的SOTA&#xff08;state of the art&#xff09;Boosting算法&#xff0c;都可以归类到梯度提升决策树算法系列。三个模…

探索LangChain的单元测试世界:主流框架全解析

探索LangChain的单元测试世界&#xff1a;主流框架全解析 引言 在软件开发过程中&#xff0c;单元测试是确保代码质量的关键环节。LangChain作为一个多语言编程工具链&#xff0c;支持多种编程语言&#xff0c;每种语言都有其对应的单元测试框架。本文将详细介绍LangChain支持…

5. JavaSE ——【适合小白的数组练习题】

&#x1f4d6;开场白 亲爱的读者&#xff0c;大家好&#xff01;我是一名正在学习编程的高校生。在这个博客里&#xff0c;我将和大家一起探讨编程技巧、分享实用工具&#xff0c;并交流学习心得。希望通过我的博客&#xff0c;你能学到有用的知识&#xff0c;提高自己的技能&a…

【区块链 + 智慧政务】澳门:智慧城市建设之证书电子化项目 | FISCO BCOS应用案例

2019 年 2 月 27 日&#xff0c;澳门政府设立的澳门科学技术发展基金与微众银行达成合作&#xff0c;通过区块链、人工智能、大数据、 云计算等创新技术&#xff0c;共同推进澳门特区的智慧城市建设与未来型城市发展&#xff0c;提升粤港澳大湾区的科创能力。在澳 门智慧城市建…

【数学建模】高温作业专用服装设计(2018A)隐式差分推导

为方便计算&#xff0c;对区域进行离散化处理&#xff0c;采用隐式差分格式进行离散计算。隐式差分格式如图&#xff1a; 每层材料内部 对第 j j j层材料: 其中&#xff0c; λ j \lambda_j λj​表示第 j j j层的热扩散率&#xff0c; c j c_j cj​表示第 j j j层的比热容…

Matplotlib库学习之pyplot.figure()函数

Matplotlib库学习之pyplot.figure()函数 一、简介 pyplot.figure() 是 Matplotlib 的 pyplot 模块中的一个函数&#xff0c;用于创建一个新的图形&#xff08;figure&#xff09;。在 Matplotlib 中&#xff0c;图形是绘图元素的容器&#xff0c;可以包含多个坐标轴&#xff…

linux需要熟悉的命令理解记忆

(1)光标插入 (1)一般模式下: i 插入到光标前方 记忆方法:在一般模式下, 光标选中字符, 我们按下 i, 就会插入光标的前方, insert, 表示插队 (2)一般模式下: a 插入到光标后方 记忆方法: 在一般模式下, 光标选中字符,a表示append, 添加或者附加的意思 (3) 如果要在行首或者行…

css实现每个小盒子占32%,超出就换行

代码 <div class"visitors"><visitor class"item" v-for"(user,index) in userArr" :key"user.id" :user"user" :index"index"></visitor></div><style lang"scss" scoped&…

java乱码问题

文章目录 1.eclipse所有修改编码的地方2.io读取文件乱码问题1.读写统一2.转换字符编码&#xff1a; 3.http请求返回乱码 1.eclipse所有修改编码的地方 2.io读取文件乱码问题 1.读写统一 如果文件是以UTF-8编码保存的&#xff0c;那么在读取文件时也应使用UTF-8编码。 2.转换…

Apple Vision Pro 和其商业未来

机器人、人工智能相关领域 news/events &#xff08;专栏目录&#xff09; 本文目录 一、Vision Pro 生态系统二、Apple Vision Pro 的营销用例 随着苹果公司备受期待的进军可穿戴计算领域&#xff0c;新款 Apple Vision Pro 承载着巨大的期望。 苹果公司推出的 Vision Pro 售…

百分点科技签约潍坊市数据产业发展战略合作

近日&#xff0c;潍坊市数据产业发展战略合作签约仪式举行&#xff0c;潍坊市人民政府副市长张震生&#xff0c;潍坊市财政局党组书记、局长王金祥&#xff0c;潍坊市大数据局党组书记陈强出席大会并致辞。百分点科技受邀进行战略合作签约&#xff0c;共同见证潍坊市数据要素市…

生成式人工智能(AI)的未来

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

深度学习模型快速开发平台推荐

前言 本文面向深度学习初学者或者工程师&#xff0c;推荐几个常用的深度学习模型快速开发平台。可以帮助初学者快速跑通模型&#xff0c;帮助工程师快速对模型进行部署和应用。 huggingface 简介 不多介绍&#xff0c;全球最大的模型托管平台&#xff0c;该平台最大的特点是…

全网超详细Redis主从部署(附出现bug原因)

主从部署 整体架构图 需要再建两个CentOs7,过程重复单机部署 http://t.csdnimg.cn/zkpBE http://t.csdnimg.cn/lUU5gLinux环境下配置redis 查看自己ip地址命令 ifconfig 192.168.187.137 进入redis所在目录 cd /opt/software/redis cd redis-stable 进入配置文件 vim redi…