享元模式
1.动机(解决的问题)
在面向对象系统中,经常需要创建很多的类和对象。比如一个系统中有成百上千、成千上万的对象,这些小对象可能有着大部分相同的信息,但却要被创建成千上万次,占据着不同的内存空间。当对象的数量过多,占用的内存过多,将导致系统运行代价过高,性能下降等问题。如果能把这些共同的信息抽取出来,形成一个对象,其他成千上万相同信息的对象引用该对象,可极大的减少内存空间占用。
2.模式概述:
享元模式运用共享技术有效地支持大量细粒度对象的复用。
3.实现方式:
享元对象拥有两种状态:内蕴状态、外蕴状态。
- 内蕴状态:指各对象相同的、不会随外在因素变化的部分,存储在共享对象内部。
- 外蕴状态:需要由外部环境来设置的、不同的部分,由客户端来维护。
单纯享元模式:
- 涉及三种角色:抽象享元角色、具体享元角色、享元工厂角色。
- 抽象享元角色:提供一个抽象接口,定义享元角色要实现的方法。
- 具体享元角色:实现抽象享元角色定义的接口,对内蕴状态存储。
- 享元工厂角色:负责享元对象的创建和管理。内部维护一享元容器,对外提供享元对象的获取方法。
- 客户端调用享元工厂角色提供的方法获取享元对象,享元工厂角色在内部容器中查找:如果该享元对象已存在,直接返回该对象;如果不存在,则创建该对象,并保存到容器中,返回给客户端。
- 客户端使用享元对象实例,通过传入不同的外部状态执行业务方法。
复合享元模式:
- 涉及四种角色:抽象享元角色、具体享元角色、复合享元角色、享元工厂角色。
- 抽象享元角色:提供一个抽象接口,定义享元角色要实现的方法。
- 具体享元角色:实现抽象享元角色定义的接口,对内蕴状态存储。
- 复合享元角色:该角色的对象不可共享,但是其内部也维护一个由多个具体享元角色组成的列表。
- 享元工厂角色:负责具体享元对象、复合享元对象的创建和管理。内部维护一享元容器,对外提供各享元对象的获取方法。
- 客户端调用享元工厂角色提供的方法获取享元对象,享元工厂角色在内部容器中查找:如果该享元对象已存在,直接返回该对象;如果不存在,则创建该对象,并保存到容器中,返回给客户端。
- 客户端使用享元对象实例,通过传入不同的外部状态执行业务方法。
- 一个复合享元对象内部,所有的具体享元对象,它们的内部状态可能不同,但外蕴状态都是相同的。
4.适用场景:
- 一个系统中有大量的对象
- 这些对象耗费大量的内存
- 这些对象的状态中的大部分都可以外部化
- 这些对象可以按照内部状态划分为很多的组,当把外部状态从对象中剔除时,每一个组都可以仅仅用一个对象代替。
- 软件系统不依赖与这些对象的身份,换言之,这些对象的身份可以是不可分辩的。