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

设计模式的艺术-享元模式

结构性模式的名称、定义、学习难度和使用频率如下表所示:

1.如何理解享元模式

  1. 当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。

  2. 在享元模式中,存储这些共享实例对象的地方称为享元池(Flyweight Pool)。可以针对每个不同的字符创建一个享元对象,将其放在享元池中,需要时再从享元池取出。如图

    image.png

  1. 享元模式以共享的方式高效地支持大量细粒度对象的重用。享元对象能做到共享的关键是区分了内部状态(Intrinsic State)和外部状态(Extrinsic State)。

    1. 内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享。例如字符的内容,不会随外部环境的变化而变化,无论在任何环境下,字符“a”始终是“a”,都不会变成“b”。

    2. 外部状态是随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用的时候,再传入享元对象内部。一个外部状态与另一个外部状态之间是相互独立的。如字符的颜色,可以在不同的地方有不同的颜色,例如有的“a”是红色的,有的“a”是绿色的;字符的大小也是如此,有的“a”是五号字,有的“a”是四号字。

  1. 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。

  2. 当系统中存在大量相同或者相似的对象时,享元模式是一种较好的解决方案。它通过共享技术实现相同或相似的细粒度对象的复用,从而节约了内存空间,提高了系统性能。

2.如何理解单纯享元模式和复合享元模式?

  1. 单纯享元

    1. 享元对象是不可分解的,它们具有单一、不可分割的内在状态,并且可以被多个外部对象共享。

    2. 例如在一个游戏中,各种颜色的小方块是享元对象。每个小方块的颜色就是它的内在状态,而且小方块本身不能再被分解为更小的部分。多个游戏场景可以共享这些具有特定颜色的小方块。

  1. 复合享元模式

    1. 由多个单纯享元对象组合而成的复合对象。

    2. 例如,在一个图形设计软件中,一个复杂的图标可能由多个基本图形元素(如线段、圆形、三角形等单纯享元对象)组成。这些基本图形元素可以被多个图标共享,而图标本身就是一个复合享元对象。

    3. 单纯享元模式相对简单,主要处理单一、不可分割的享元对象。而复合享元模式更复杂一些,需要处理享元对象的组合和共享。

3.关于享元模式的几点补充

  1. 享元模式通常需要和其他模式一起联用,几种常见的联用方式如下:

    1. 在享元模式的享元工厂类中通常提供一个静态的工厂方法用于返回享元对象,使用简单工厂模式来生成享元对象。

    2. 在一个系统中,通常只有唯一一个享元工厂,因此可以使用单例模式进行享元工厂类的设计。

4.享元模式的优缺点是什么?

  1. 优点

    1. 减少内存使用:通过共享相同或相似的对象,大大减少了系统中对象的数量,从而降低了内存消耗。

    2. 提高性能:由于减少了对象的创建和销毁,提高了系统的性能。

    3. 增强系统的可扩展性:可以方便地添加新的享元对象或修改现有享元对象的共享方式,而对系统的其他部分影响较小。

  1. 缺点

    1. 适用场景有限:并非所有情况都适合使用享元模式,如果对象的共享率不高,可能无法带来明显的性能提升,反而增加了系统的复杂性。

    2. 增加系统复杂性:需要额外的逻辑来管理享元对象的共享和获取,增加了代码的复杂性和理解难度。

5.享元模式适用场景有哪些?

  1. 系统中存在大量相似的对象:例如在一个文本编辑软件中,大量重复出现的字符对象可以使用享元模式来共享。

  2. 对象创建和销毁的成本较高:如果创建一个对象需要消耗较多的资源,如时间、内存等,通过共享已有的对象可以避免重复创建。

  3. 需要缓存大量细粒度对象:比如在一个网页中,相同样式的小图标可以被共享,以减少内存占用。

以上内容为根据书本内容配合搜索引擎整理得来,目的是为了学习,要是有侵权的情况发生,请联系我,我会立即予以删除,谢谢!

一起成长,人生是马拉松,可以跑得慢,但一定要在路上。

http://www.lryc.cn/news/526280.html

相关文章:

  • Linux的权限和一些shell原理
  • 【Postgres_Python】使用python脚本批量创建和导入多个PG数据库
  • Ubuntu安装GitLab
  • 网络知识小科普--5
  • JavaScript学习记录23
  • VScode 开发 Springboot 程序
  • .git/hooks/post-merge 文件的作用
  • Kafak 单例生产者实现-C#操作
  • Cursor开发前端的详细过程
  • 基于微信小程序的移动学习平台的设计与实现(LW+源码+讲解)
  • atheris从安装到fuzz输入输出解读
  • 「 机器人 」系统辨识实验浅谈
  • 基于Flask的哔哩哔哩评论数据可视化分析系统的设计与实现
  • [央企大赛 2025] pwn
  • C语言初阶--折半查找算法
  • Python!从0开始学爬虫:(一)HTTP协议 及 请求与响应
  • [ Spring ] Spring Cloud Gateway 2025 Comprehensive Overview
  • 【项目初始化】自定义异常处理
  • Windows10安装MySQL找不到MSVCR120.dll和MSVCP120.dll问题解决
  • 【嵌入式】总结——Linux驱动开发(三)
  • 计算机图形学:实验三 光照与阴影
  • 「 机器人 」扑翼飞行器混合控制策略缺点浅谈
  • 蓝桥杯算法日常|c\c++常用竞赛函数总结备用
  • 每日十题八股-2025年1月24日
  • tomcat的accept-count、max-connections、max-threads三个参数的含义
  • 【无标题】mysql python 连接
  • linux naive代理设置
  • [STM32 - 野火] - - - 固件库学习笔记 - - -十一.电源管理系统
  • DBO优化最近邻分类预测matlab
  • 【深入理解FFMPEG】命令行阅读笔记