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

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

文章目录

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
【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)
【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)
51 2
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 XML Java
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
30 0
|
1月前
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
40 0
|
3月前
|
设计模式
建模底层逻辑问题之以命令设计模式为例,要用定义法建模,如何实现
建模底层逻辑问题之以命令设计模式为例,要用定义法建模,如何实现
|
2月前
|
设计模式 Java 关系型数据库
设计模式——设计模式简介和七大原则
设计模式的目的和核心原则、单一职责原则、接口隔离原则、依赖倒转原则、里氏替换原则、开闭原则、迪米特法则、合成复用原则
设计模式——设计模式简介和七大原则
|
2月前
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
|
2月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
46 2
|
1月前
|
设计模式 算法 Java
【设计模式】策略模式(定义 | 特点 | Demo入门讲解)
【设计模式】策略模式(定义 | 特点 | Demo入门讲解)
21 0
|
3月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)