享元模式

1.动机(解决的问题)

在面向对象系统中,经常需要创建很多的类和对象。比如一个系统中有成百上千、成千上万的对象,这些小对象可能有着大部分相同的信息,但却要被创建成千上万次,占据着不同的内存空间。当对象的数量过多,占用的内存过多,将导致系统运行代价过高,性能下降等问题。如果能把这些共同的信息抽取出来,形成一个对象,其他成千上万相同信息的对象引用该对象,可极大的减少内存空间占用。

2.模式概述:

享元模式运用共享技术有效地支持大量细粒度对象的复用。

3.实现方式:

享元对象拥有两种状态:内蕴状态、外蕴状态。

  • 内蕴状态:指各对象相同的、不会随外在因素变化的部分,存储在共享对象内部。
  • 外蕴状态:需要由外部环境来设置的、不同的部分,由客户端来维护。

单纯享元模式:

  • 涉及三种角色:抽象享元角色、具体享元角色、享元工厂角色。
  1. 抽象享元角色:提供一个抽象接口,定义享元角色要实现的方法。
  2. 具体享元角色:实现抽象享元角色定义的接口,对内蕴状态存储。
  3. 享元工厂角色:负责享元对象的创建和管理。内部维护一享元容器,对外提供享元对象的获取方法。
  4. 客户端调用享元工厂角色提供的方法获取享元对象,享元工厂角色在内部容器中查找:如果该享元对象已存在,直接返回该对象;如果不存在,则创建该对象,并保存到容器中,返回给客户端。
  5. 客户端使用享元对象实例,通过传入不同的外部状态执行业务方法。

享元模式


复合享元模式:

  • 涉及四种角色:抽象享元角色、具体享元角色、复合享元角色、享元工厂角色。
  1. 抽象享元角色:提供一个抽象接口,定义享元角色要实现的方法。
  2. 具体享元角色:实现抽象享元角色定义的接口,对内蕴状态存储。
  3. 复合享元角色:该角色的对象不可共享,但是其内部也维护一个由多个具体享元角色组成的列表。
  4. 享元工厂角色:负责具体享元对象、复合享元对象的创建和管理。内部维护一享元容器,对外提供各享元对象的获取方法。
  5. 客户端调用享元工厂角色提供的方法获取享元对象,享元工厂角色在内部容器中查找:如果该享元对象已存在,直接返回该对象;如果不存在,则创建该对象,并保存到容器中,返回给客户端。
  6. 客户端使用享元对象实例,通过传入不同的外部状态执行业务方法。
  7. 一个复合享元对象内部,所有的具体享元对象,它们的内部状态可能不同,但外蕴状态都是相同的。

享元模式

4.适用场景:

  1. 一个系统中有大量的对象
  2. 这些对象耗费大量的内存
  3. 这些对象的状态中的大部分都可以外部化
  4. 这些对象可以按照内部状态划分为很多的组,当把外部状态从对象中剔除时,每一个组都可以仅仅用一个对象代替。
  5. 软件系统不依赖与这些对象的身份,换言之,这些对象的身份可以是不可分辩的。
如:jdk中的string类,就是享元模式的实现。