Java设计模式学习篇享元设计模式

享元模式(Flyweight Pattern)享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。比如我们在多线程环境下的线程池、数据库连接下的连接池等,它们都属于享元设计模式。

如下图所示,是一个享元设计模式典型的类图。

FlyWeightFactory类负责管理和提供FlyWeight对象。FlyWeight是一个抽象类或者接口,下面的FlyWeight1或者FlyWeight2是具体实现类。当Client请求FlyWeightFactory提供一个FlyWeight时,FlyWeightFactory首先检查当前空闲的FlyWeight个数,如果没有FlyWeight,就重新创建一个。(在数据库连接池中,假如当前连接池中没有空闲connection,那么新的请求会等待其他请求超时,某一个连接超时会发生异常从而向连接池释放一个连接Connection)。

如下,我们实现一个简单的数据库连接池。

代码如下:

大家也可以去看看源码,这里只是简单写了一下。

总结:享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。

思考1:享元设计模式和工厂设计模式很相似,区别在哪?

区别在于工厂设计模式提供产品,而不管理个数。享元设计模式可以初始化大小。比如我们在数据库连接池初始化,可以配置最大连接数量、最小空闲数量。其中默认创建了n个连接池,只有当外部需求超过了最大数量,才会采取新new一个对象(或者等待其他释放资源)。

思考2:享元设计模式可以与哪些设计模式合并使用,能举例吗?

我们在设计享元设计模式时,可以和单例设计模式一起使用。也可以和其他设计模式使用,比如装饰者模式。在apache开源Commmons工具包下的数据库连接池中,就采用了装饰者设计模式对connection对象的close()方法进行装饰,使其向连接池Pool提交该connection的使用权,而不是销毁该connection连接。

思考3:享元设计模式应用场景举例?

我们上文提到了在多线程下面的线程池和数据库连接访问的连接池都属于享元设计。比如我们要设计一个黑白棋游戏,我们可以采用享元设计模式,设计黑棋和白棋。当游戏者走白棋,就从享元工厂中调取白棋的相关熟悉(比如传入字符“白棋”,得到白棋对象,该对象包含了白棋的形状、颜色等属性,这些属性都是一样的,可共享的)。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180515G0HZXO00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券