设计模式(14) -结构型模式 之 享元模式

1. 享元模式概述

文章例子来自一个b站的视频。

1.1 定义

享元模式(FlyWeight),运用共享技术有效的支持大量细粒度的对象
--------------------- 来自百度百科

1.2 使用场景

系统中有大量对象,这些对象消耗大量内存,并且对象的状态大部分可以外部化时,我们就可以考虑选用享元

内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存。

举个大家都明白的例子:
比如你设计一个五子棋或者围棋游戏。里面有黑棋,白棋,两种棋子,
辣么大一个棋盘,能下好好几十 个,或者几百(不会下不知道????)个棋子。你想一个棋子弄一个对象?好家伙,几十几百个对象呢。是不是有点浪费了。

那么你思考一下,你下的这些棋子,是不是很相似?只是下的位置不同。这就叫上面说的 完全相同或者相似的对象

1.3 核心概念

享元对象做到共享的这么一个概念,就是如下两个概念

  • 内部状态:可以共享,不会随环境变化而改变
  • 外部状态:不可以共享,会随环境变化而改变

那么为什么要这么做呢。相信大家都知道,你这个相似的对象共享啊,总得有相同的部分,有不同的部分吧(经常变化的部分)
---------------------------------------------分割-------------------------
那么这个不变的啊。就是这个内部状态,比如这个五子棋这个黑棋白棋,他就不变化,你下一盘子棋,总不能上面弄出来个绿色的吧?这个棋子的颜色可以理解为内部状态。

那么这个变的啊,很明显。你一盘子棋子,都是黑色白色的一大堆。他们总有不同的方面吧?那么很明显,他们的坐标 就是再变化的,这个经常变化的。随着环境变化而变化的,他就是外部状态。

相信大家能够理解,下面也是使用这个例子进行演示。

2. 代码

2.1 场景介绍

这个场景就是我们上面介绍的那个 五子棋或者是围棋的那个场景。我们改如何设计这个棋子对象,来达到节省空间的目的呢?

2.2 分析

因为可以看到啊,这个一盘棋子,只有黑色和白色之分,那么这个两个对象就够了。那么那个坐标就是外部的这个状态

2.3 类图

2.3.1 百度上的类图

总感觉有点别扭,我也不知道UnsharedConcreteFlyweight 要实现这个接口。????可能这个模式学的不够好吧我。
设计模式(14) -结构型模式 之 享元模式

2.3.2 本例类图

设计模式(14) -结构型模式 之 享元模式

2.4 代码

  • 接口类Flyweight
    设计模式(14) -结构型模式 之 享元模式

  • concreteFlyweight
    设计模式(14) -结构型模式 之 享元模式

  • 外部状态类,也就是说不共享的类。这边是一个pojo
    设计模式(14) -结构型模式 之 享元模式

  • 创建享元对象的工厂类
    设计模式(14) -结构型模式 之 享元模式

  • client
    设计模式(14) -结构型模式 之 享元模式

  • 运行结果
    设计模式(14) -结构型模式 之 享元模式

3. 优缺点与典型场景

3.1 优点

享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率

从上面的例子也能看出来,我就创建了两个对象

3.2 缺点

就是找出外部状态和内部状态也是比较不容易的。
而且一个必然就是增加了系统的复杂度

3.3 典型应用

享元模式经典的应用场景是需要缓冲池的场景,如String 常量池、数据库连接池

3. 总结

记录一下,没啥总结了。这个模式应该用的不是很多,应该不会很常用。