搭建邮箱系统的意义与方法解析,提升效率与安全性
874
2022-05-29
文章目录
I . 享元模式 简介
II . 享元模式 内部状态 和 外部状态
III . 享元模式 适用场景
IV . 享元模式 优缺点
V . 享元模式 相关模式
VI . 享元模式 相关角色
1 . 享元模式 简介 :
享元模式的核心是
对象池 ,
使用对象时 , 先从对象池中获取对象 ,
如果对象池中没有 , 创建一个 , 放入对象池 , 然后再从对象池中获取 ;
( 只能从对象池中拿对象 , 不能自己创建 )
① 设计模式类型 :
结构性 ;
② 享元模式 概念 :
通过减少创建对象数量 , 改善应用中使用对象的结构 , 使用
共享对象 ( 对象池中的对象 )
, 支持多个
细粒度对象 ( 使用时的大量对象 ) ;
③ 好处 :
减少创建对象的数量 , 从而减少内存的占用 , 提高性能 ;
2 . 细粒度对象 和 共享对象 :
目的是为了提高程序性能 ;
① 细粒度对象 :
是内存中的数量庞大的对象 ;
实际使用的数量庞大的对象 ;
② 共享对象 :
多个细粒度对象共享的部分数据 ;
对象缓存池中存储的对象 ;
③ 举例说明 :
使用字符串值 “abc” ,
首次使用 , 创建该字符串 , 将其放入字符串缓存池中 , 这个缓存池中的字符串就是
"共享对象" ,
应用中要大量使用 “abc” 字符串 , 比如使用 10 万个 “abc” 字符串对象 , 这 10 万个字符串对象就是
"细粒度对象" ,
此时肯定不会创建这么多对象 , 这 10 万个对象使用时从字符串缓存池中查找缓存的那个
"共享对象"
即可 , 这样节省了很大的内存开销 ;
3 . 享元模式示例 :
Java 的 String 类型就是用了享元模式的设计模式 ;
① 定义字符串 : String str = "Hello" ;
② 内存中已有该字符串 :
如果之前已经有该字符串 , 就直接将字符串缓存池中的字符串返回 ,
③ 新字符串 :
如果内存中没有该字符串 , 就创建一个新的字符串 , 放入缓存池中 ;
享元模式就是池技术 , 如字符串池 , 数据库连接池 等 ;
使用对象时 , 先从池中查找 , 没有找到再创建该对象 , 然后放入对象池中 ;
4 . 享元模式使用策略 :
用户想要调用一个对象 , 去对象池中查找 , 如果对象池中有该对象 , 那么直接使用该对象 , 如果没有 , 创建该对象 , 放入对象池中 , 然后再从对象池中获取该对象 ;
对象对比 :
这里涉及到一个问题 , 如何确定对象池中的对象是不是用户想要使用的对象呢 ?
5 . 引入 内部状态 和 外部状态 :
对象对比问题引出这两个概念 , 对象中有很多数据 , 那么使用什么数据来确定两个对象是否一致呢 , 这里使用 对象的 外部状态 来确定 ;
① 内部状态 :
对象的内部状态不能作为对象对比的依据 , 所有对象的内部状态都是一样的数据 ;
② 外部状态 :
对象的外部状态每个都不一样 , 每个对象都有一个唯一 外部状态 值 , 类似于 身份证 , 哈希码 这一类的信息 ;
③ 身份标识 :
在线程池中 , 使用外部状态信息 , 唯一确定一个对象 , 作为对象的标识信息 ;
1 . 概念引入 :
区分这两个概念的目的是为了维护享元模式的对象池 , 当用户想要使用某个对象时 , 如何确定对象池中的对象是否是用户想要调用的对象呢 , 这里就需要一些数据进行对比 , 数据一致 , 就说明是用户想要的对象 , 数据不一致 , 就需要创建新对象 , 放入对象池 ;
① 内部状态 :
有些数据所有的对象都一样 , 显然不能当做对象一致性对比的依据 , 这就是 内部状态 ;
② 外部状态 :
有些数据每个对象都不一样 , 根据该数据确定对象的唯一性 , 相当于 哈希码 , 身份证号 , 档案编号 这一类的数据 , 这就是外部状态 ;
内部状态 和 外部状态 本质是 信息数据
2 . 内部状态 ( 共享信息 ) :
在享元模式中的对象中 , 不随环境改变而改变的信息 ;
① 共享信息 :
内部状态就是可以被共享的信息 ;
② 存储位置 :
该信息存储在享元对象内部 ;
③ 存储形式 :
该信息作为对象的附加数据 , 不在具体的对象中存储 , 可以被多个对象共享 ;
3 . 外部状态 ( 不可共享信息 ) :
随着外部环境改变 , 对象内部跟着改变 , 这部分内容就不能进行共享 ;
不可共享 :
外部状态不可被共享 , 每个值都必须在不同的对象中维护 ;
1 . 享元模式 适用场景 :
① 底层开发 :
某个系统的底层开发 , 对性能要求比较高 , 可使用享元模式 ;
② 缓冲池 :
系统中实例对象数量庞大 , 需要缓冲池处理这些对象 ;
2 . 享元模式使用前提 :
系统中存在大量的对象 , 这些对象状态大部分功能可以外部化 , 将这些功能抽离出来 , 只在内存中保留一份 ;
① 分离对象功能 :
系统中如果内存中持有大量对象 , 可能会溢出 , 将这些对象相同的部分分离出来 ;
② 用户调用行为 :
如果有相同的业务请求 , 则优先使用内存中已有的对象进行处理 , 避免使用大量相同的对象 ;
③ 注意 :
这里只有在内存中有大量相同对象时 , 才考虑享元模式 , 如果内存中某类型的对象数量较少 , 没有必要使用该模式 ;
1 . 享元模式 优点 :
① 降低内存占用 :
减少在内存中创建对象的数量 , 节省了内存 , 提高了效率 ;
② 减少创建对象开销 :
创建对象时需要占用一定的开销 , 如 new 操作 ; 可能构造函数中有访问 文件 , 数据库 , 网络 等操作 , 也可以避免这些开销 ;
2 . 享元模式 缺点 :
① 线程安全问题 :
在类中为了追求性能 , 一般使用的是 HashMap , ArrayList 等数据 , 这些数据结构都是线程不安全的 ; 使用 HashTable , Vector 线程安全了 , 但是性能会下降很多 ; 折中使用 ConcurrentHashMap 等 concurrent 包下的集合 ;
② 增加复杂性 :
将一个类拆解成多个类 , 系统复杂性肯定增加了 ;
1 . 享元模式 与 代理模式 :
代理模式需要代理某个类 , 生成该类需要花费较多的资源和时间 , 可以使用享元模式提高处理速度 ;
2 . 享元模式 与 单例模式 :
容器单例模式 , 复用对象 ;
1 . 抽象享元角色 :
抽象类 , 其中定义了 内部对象 , 外部对象 , 抽象行为 ;
① 内部对象 :
享元模式中 , 不关心该类数据 ;
② 外部对象 :
该值只能设置一次值 , 不能二次赋值 , 否则会造成对象池管理混乱 ; 一般要设置成 final 类型的 , 在构造函数中赋值 ;
③ 抽象行为 :
这是客户调用的方法 ;
客户使用享元模式时 , 创建的对象就是 抽象的享元角色 对象 , 调用的是抽象行为 ;
享元工厂管理时 , 也管理 抽象享元角色 对象 ;
2 . 具体享元角色 :
在构造函数中设置外部状态 , 实现自己的业务逻辑 ;
3 . 享元工厂角色 :
在享元工厂中 , 维护对象池 , 当用户调用 享元对象 时 , 从对象池中获取该对象 , 如果没有获取到 , 那么创建新的 享元对象 , 放入对象池中 , 并返回该对象 ;
4 . 用户调用 :
用户声明 抽象享元类对象 , 调用其定义的抽象行为 ;
任务调度
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。