【设计模式】享元模式 简介 ( 定义 | 对象池 | 内部状态 | 外部状态 | 适用场景 | 相关角色 )

简介: 【设计模式】享元模式 简介 ( 定义 | 对象池 | 内部状态 | 外部状态 | 适用场景 | 相关角色 )

文章目录

I . 享元模式 简介

II . 享元模式 内部状态 和 外部状态

III . 享元模式 适用场景

IV . 享元模式 优缺点

V . 享元模式 相关模式

VI . 享元模式 相关角色



I . 享元模式 简介


1 . 享元模式 简介 : 享元模式的核心是 对象池 , 使用对象时 , 先从对象池中获取对象 , 如果对象池中没有 , 创建一个 , 放入对象池 , 然后再从对象池中获取 ; ( 只能从对象池中拿对象 , 不能自己创建 )



① 设计模式类型 : 结构性 ;


② 享元模式 概念 : 通过减少创建对象数量 , 改善应用中使用对象的结构 , 使用 共享对象 ( 对象池中的对象 ) , 支持多个 细粒度对象 ( 使用时的大量对象 ) ;


③ 好处 : 减少创建对象的数量 , 从而减少内存的占用 , 提高性能 ;



2 . 细粒度对象 和 共享对象 : 目的是为了提高程序性能 ;



① 细粒度对象 : 是内存中的数量庞大的对象 ; 实际使用的数量庞大的对象 ;


② 共享对象 : 多个细粒度对象共享的部分数据 ; 对象缓存池中存储的对象 ;


③ 举例说明 : 使用字符串值 “abc” , 首次使用 , 创建该字符串 , 将其放入字符串缓存池中 , 这个缓存池中的字符串就是 "共享对象" , 应用中要大量使用 “abc” 字符串 , 比如使用 10 万个 “abc” 字符串对象 , 这 10 万个字符串对象就是 "细粒度对象" , 此时肯定不会创建这么多对象 , 这 10 万个对象使用时从字符串缓存池中查找缓存的那个 "共享对象" 即可 , 这样节省了很大的内存开销 ;



3 . 享元模式示例 : Java 的 String 类型就是用了享元模式的设计模式 ;


① 定义字符串 : String str = "Hello" ;


② 内存中已有该字符串 : 如果之前已经有该字符串 , 就直接将字符串缓存池中的字符串返回 ,


③ 新字符串 : 如果内存中没有该字符串 , 就创建一个新的字符串 , 放入缓存池中 ;



享元模式就是池技术 , 如字符串池 , 数据库连接池 等 ;

使用对象时 , 先从池中查找 , 没有找到再创建该对象 , 然后放入对象池中 ;



4 . 享元模式使用策略 : 用户想要调用一个对象 , 去对象池中查找 , 如果对象池中有该对象 , 那么直接使用该对象 , 如果没有 , 创建该对象 , 放入对象池中 , 然后再从对象池中获取该对象 ;


对象对比 : 这里涉及到一个问题 , 如何确定对象池中的对象是不是用户想要使用的对象呢 ?



5 . 引入 内部状态 和 外部状态 : 对象对比问题引出这两个概念 , 对象中有很多数据 , 那么使用什么数据来确定两个对象是否一致呢 , 这里使用 对象的 外部状态 来确定 ;



① 内部状态 : 对象的内部状态不能作为对象对比的依据 , 所有对象的内部状态都是一样的数据 ;


② 外部状态 : 对象的外部状态每个都不一样 , 每个对象都有一个唯一 外部状态 值 , 类似于 身份证 , 哈希码 这一类的信息 ;


③ 身份标识 : 在线程池中 , 使用外部状态信息 , 唯一确定一个对象 , 作为对象的标识信息 ;




II . 享元模式 内部状态 和 外部状态


1 . 概念引入 : 区分这两个概念的目的是为了维护享元模式的对象池 , 当用户想要使用某个对象时 , 如何确定对象池中的对象是否是用户想要调用的对象呢 , 这里就需要一些数据进行对比 , 数据一致 , 就说明是用户想要的对象 , 数据不一致 , 就需要创建新对象 , 放入对象池 ;



① 内部状态 : 有些数据所有的对象都一样 , 显然不能当做对象一致性对比的依据 , 这就是 内部状态 ;


② 外部状态 : 有些数据每个对象都不一样 , 根据该数据确定对象的唯一性 , 相当于 哈希码 , 身份证号 , 档案编号 这一类的数据 , 这就是外部状态 ;



内部状态 和 外部状态 本质是 信息数据



2 . 内部状态 ( 共享信息 ) : 在享元模式中的对象中 , 不随环境改变而改变的信息 ;



① 共享信息 : 内部状态就是可以被共享的信息 ;


② 存储位置 : 该信息存储在享元对象内部 ;


③ 存储形式 : 该信息作为对象的附加数据 , 不在具体的对象中存储 , 可以被多个对象共享 ;



3 . 外部状态 ( 不可共享信息 ) : 随着外部环境改变 , 对象内部跟着改变 , 这部分内容就不能进行共享 ;


不可共享 : 外部状态不可被共享 , 每个值都必须在不同的对象中维护 ;




III . 享元模式 适用场景


1 . 享元模式 适用场景 :



① 底层开发 : 某个系统的底层开发 , 对性能要求比较高 , 可使用享元模式 ;


② 缓冲池 : 系统中实例对象数量庞大 , 需要缓冲池处理这些对象 ;



2 . 享元模式使用前提 : 系统中存在大量的对象 , 这些对象状态大部分功能可以外部化 , 将这些功能抽离出来 , 只在内存中保留一份 ;



① 分离对象功能 : 系统中如果内存中持有大量对象 , 可能会溢出 , 将这些对象相同的部分分离出来 ;


② 用户调用行为 : 如果有相同的业务请求 , 则优先使用内存中已有的对象进行处理 , 避免使用大量相同的对象 ;


③ 注意 : 这里只有在内存中有大量相同对象时 , 才考虑享元模式 , 如果内存中某类型的对象数量较少 , 没有必要使用该模式 ;




IV . 享元模式 优缺点


1 . 享元模式 优点 :



① 降低内存占用 : 减少在内存中创建对象的数量 , 节省了内存 , 提高了效率 ;


② 减少创建对象开销 : 创建对象时需要占用一定的开销 , 如 new 操作 ; 可能构造函数中有访问 文件 , 数据库 , 网络 等操作 , 也可以避免这些开销 ;



2 . 享元模式 缺点 :



① 线程安全问题 : 在类中为了追求性能 , 一般使用的是 HashMap , ArrayList 等数据 , 这些数据结构都是线程不安全的 ; 使用 HashTable , Vector 线程安全了 , 但是性能会下降很多 ; 折中使用 ConcurrentHashMap 等 concurrent 包下的集合 ;


② 增加复杂性 : 将一个类拆解成多个类 , 系统复杂性肯定增加了 ;




V . 享元模式 相关模式


1 . 享元模式 与 代理模式 : 代理模式需要代理某个类 , 生成该类需要花费较多的资源和时间 , 可以使用享元模式提高处理速度 ;



2 . 享元模式 与 单例模式 : 容器单例模式 , 复用对象 ;




VI . 享元模式 相关角色


1 . 抽象享元角色 : 抽象类 , 其中定义了 内部对象 , 外部对象 , 抽象行为 ;



① 内部对象 : 享元模式中 , 不关心该类数据 ;


② 外部对象 : 该值只能设置一次值 , 不能二次赋值 , 否则会造成对象池管理混乱 ; 一般要设置成 final 类型的 , 在构造函数中赋值 ;


③ 抽象行为 : 这是客户调用的方法 ;



客户使用享元模式时 , 创建的对象就是 抽象的享元角色 对象 , 调用的是抽象行为 ;

享元工厂管理时 , 也管理 抽象享元角色 对象 ;



2 . 具体享元角色 : 在构造函数中设置外部状态 , 实现自己的业务逻辑 ;



3 . 享元工厂角色 : 在享元工厂中 , 维护对象池 , 当用户调用 享元对象 时 , 从对象池中获取该对象 , 如果没有获取到 , 那么创建新的 享元对象 , 放入对象池中 , 并返回该对象 ;



4 . 用户调用 : 用户声明 抽象享元类对象 , 调用其定义的抽象行为 ;


目录
相关文章
|
1月前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
54 4
|
1月前
|
设计模式 消息中间件 存储
18个并发场景的设计模式详解,有没有你的盲区
这些模式在多线程并发编程中非常有用`。在分布式应用中,并发场景无处不在,理解和掌握这些并发模式的编码技巧,有助于我们在开发中解决很多问题,这要把这些与23种设计模式混淆了,虽然像单例模式是同一个,但这个是考虑并发场景下的应用。内容比较多,V哥建议可以收藏起来,即用好查。拜拜了您誒,晚安。
18个并发场景的设计模式详解,有没有你的盲区
|
1月前
|
设计模式 存储 前端开发
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web
37 4
|
1月前
|
设计模式 Go
[设计模式 Go实现] 结构型~享元模式
[设计模式 Go实现] 结构型~享元模式
|
1月前
|
设计模式 存储 SQL
第四篇 行为型设计模式 - 灵活定义对象间交互
第四篇 行为型设计模式 - 灵活定义对象间交互
|
1月前
|
设计模式 Java 开发者
【搞懂设计模式】享元模式:共享节约,皆大欢喜!
【搞懂设计模式】享元模式:共享节约,皆大欢喜!
31 0
|
1月前
|
设计模式 存储 Java
小谈设计模式(27)—享元模式
小谈设计模式(27)—享元模式
|
1月前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
1月前
|
设计模式 存储 Java
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
[设计模式Java实现附plantuml源码~结构型]实现对象的复用——享元模式
|
1月前
|
设计模式 存储 安全
【设计模式系列笔记】享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来最小化内存使用或计算开销,以提高性能。该模式适用于需要大量相似对象的场景,通过共享这些相似对象的部分状态,可以有效减少内存消耗。
44 0