设计模式的艺术之道–享元模式
本系列内容思路分析借鉴了刘伟老师的博文内容,同时改用C#代码进行代码的演示和分析(Java资料过多 C#表示默哀).
本系列全部源码均在文末地址给出。
本系列开始讲解结构型模式,关注如何将现有类或对象组织在一起形成更加强大的结构。
不同的结构型模式从不同的角度组合类或对象,它们在尽可能满足各种面向对象设计原则的同时为类或对象的组合提供一系列巧妙的解决方案。
- 类结构型模式
关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系 - 可以减少内存中对象的数量,使得相同或者相似的对象在内存中只保存一份,从而可以节约系统资源,提高系统性能
- 外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享
- 使得系统变得复杂,需要分离出内部状态和外部状态
- 享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长
1.2情景实例
问题描述
– 围棋棋子的设计
菜鸟软件公司开发人员通过对围棋软件进行分析,发现在围棋棋盘中包含大量的黑子和白子,它们的形状、大小都一模一样,只是出现的位置不同而已。如果将每一个棋子都作为一个独立的对象存储在内存中,将导致该围棋软件在运行时所需内存空间较大,如何降低运行代价、提高系统性能是Sunny公司开发人员需要解决的一个问题。为此引入了享元模式。
现有缺点(未来变化)
开发人员通过对围棋棋子进行进一步分析,发现虽然黑色棋子和白色棋子可以共享,但是它们将显示在棋盘的不同位置,如何让相同的黑子或者白子能够多次重复显示且位于一个棋盘的不同地方br> 如何改进
就是将棋子的位置定义为棋子的一个外部状态,在需要时再进行设置。客户端进行设置外部状态。(通过传递参数设置,不要设置在棋子的自身字段属性中 否则就属于棋子了)。
内部状态(Intrinsic State):存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享(例如:字符的内容 白色棋子 黑色棋子)
外部状态(Extrinsic State):随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用的时候再传入到享元对象内部。一个外部状态与另一个外部状态之间是相互独立的(例如:字符的颜色和大小 棋子在棋盘的位置)
改进UML类图
改进后的优点
现存的缺点
举例:Word字体的装饰功能 字体本身是为了显示 但是可以变成新的颜色 变成新的字体 新的字
享元模式和对象池
从某种角度享元模式和对象池可以认为是同一种技术。
享元模式原型一般同类型只有一个储存在原型池中,如黑白棋子各一个 ,并且外部状态是通过参数传递设置。
对象池中的共享实例(如FPS的子弹),可能会因为使用频繁而产生多个,客户端使用时,先取出对象池汇总实例,同时对外部状态进行设置(子弹初始位置 初始速度等),对象使用完毕需要放回对象池。
实例源代码
GitHub地址
百度云地址:链接: https://pan.baidu.com/s/1nvoVz6p 密码: rhxh
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!