一、享元模式介绍
享元模式(Flyweight)结构型模式,对象之间的组合模式。
享元模式通过共享相同或者相似的对象,以此来复用对象,节省内存,提高系统性能。
享元模式的本质是分离与共享。
分离会变的内容和不会变的内容,共享不会变**的内容。不会变的内容又叫做内部状态,会变的内容又叫做外部状态。
二、JDK 中的享元模式
以 Integer 为例,查阅 Integer 相关源码。![[设计模式]-[结构型]-享元-介绍及应用 - 图1](/uploads/projects/it-learn@java-base/160699492998ac763caf66a7a441f1d2.webp)
JDK 中的 Integer 在初始化默认创建 Integer 对象池,缓存了 -128~127 之间的数值对象。
而这个对象池中的共享对象就是用来给其他类共享使用的。
三、模拟享元模式案例
以游戏按键为例,在游戏中,可以根据自身的操作习惯设定不同的操作方案,针对每个在线用户都有其操作数据对象,会占用很大的内存,这时候就可以使用享元模式进行对象共享。
享元模式的宗旨就是:分离变和不变。
不变:对于 PC 用户来说,支持的所有操作键就是键盘。键盘中的操作键数是不变的。
变:相同的键盘按钮,比如:W ,所代表的的功能是不一样的。
未使用享元模式前原始代码实现如下![[设计模式]-[结构型]-享元-介绍及应用 - 图2](/uploads/projects/it-learn@java-base/f22507067a5c74b61a2da91cec01d120.webp)
如上图,关于按键的功能全部定义在了 KeyboardButton 类中,每一个用户对应的每一个按键功能都对应着一个 KeyboardButton 实例对象。
通过享元模式实现的代码如下:![[设计模式]-[结构型]-享元-介绍及应用 - 图3](/uploads/projects/it-learn@java-base/206c3856c20d51d936d4b95d24266e44.webp)
如上图,将原始的 KeyboardButton 进行拆分,根据 变 和 不变 进行拆分。
将不变的内容从 KeyboardButton 中拆分出来构建一个新的类 KeyboardButtonUnit ,该类中存放都是不变的内容,如:按键名称,标识等。该对象实例供所有的使用者共享。
将变的内容,保留在 KeyboardButton 中,例如:该按键具体表示的操作行为等。
在实现享元模式时,可以构建一个工厂类,如上图:KeyboardButtonUnitFactory ,该工厂类用来初始化共享对象 ,如:KeyboardButtonUnit。
通过对比,使用了享元模式能够减少对象的频繁创建所导致的内存溢出或者频繁的垃圾回收影响应用性能
四、享元模式对比单例和原型
原型模式:拷贝复制原始实例对象。
单例模式:保证类在某个环境下的单一实例。
享元模式:分离出可以共享的变的对象。
原型模式 vs 享元模式
原型模式通过复制已有的实例对象,针对共享的原型 倾向于实现复用,享元模式针对 共享对象,倾向于共享使用。
单例模式 vs 享元模式
单例实现的是同一个特定环境下实例的唯一性,针对是一个对象实例的共享使用。
享元模式是实现的多个对象共享对象池,注重的是节约内存空间,提高性能。
【公众号】花好夜猿
