亨元模式(Flyweight Pattern)可以理解成为轻量级模式,是一种软件设计模式。
面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
亨元模式结构图图1Flyweight模式结构图1.亨元模式的用意亨元模式是对象的结构模式。亨元模式以共享的方式高效地支持大量的细粒度对象。
亨元模式能做到共享的关键是区分内蕴状态和外蕴状态
一个内蕴状态是存储在亨元对象内部的,并且是不会随环境改变而有所不同的。因此,一个亨元可以具有内蕴状态并可以共享。
一个外蕴状态是随环境改变而改变的、不可以共享的状态。亨元对象的外蕴状态必须由客户端保存,并在亨元对象被创建之后,
在需要使用的时候再传入到亨元对象内部。
外蕴状态不可以影响亨元对象的内蕴状态的,它们是相互独立的。2.亨元模式的种类根据所涉及的亨元对象的北部表象,亨元模式可以分为单纯亨元模式和复合亨元模式两种形式。3.亨元模式的实现1)单纯亨元模式涉及的角色
1-抽象亨元角色:此角色是所有的具体亨元类的超类,为这些规定出需要实现的公共接口,那些需要外蕴状态的操作
可以通过方法的参数传入。抽象亨元的接口使得亨元变得可能,但是并不强制子类实行共享,因此并非所有的亨元
对象都是可以共享的
2-具体亨元角色:实现抽象亨元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
亨元对象的内蕴状态必须与对象所处的周围环境无关,从而使得亨元对象可以在系统内共享。有时候具体亨元角色
又叫做单纯具体亨元角色,因为复合亨元角色是由单纯具体亨元角色通过复合而成的
3-复合亨元角色:复合亨元角色所代表的对象是不可以共享的,但是一个复合亨元对象可以分解成为多个本身是单纯亨元
对象的组合。复合亨元角色又称做不可共享的亨元对象。
4-亨元工厂角色:本角色负责创建和管理亨元角色。本角色必须保证亨元对象可以被系统适当地共享。
当一个客户端对象请求一个亨元对象的时候,亨元工厂角色需要检查系统中是否已经有一个符合要求的亨元对象,
如果已经有了,亨元工厂角色就应当提供这个已有的亨元对象;如果系统中没有一个适当的亨元对象的话,
亨元工厂角色就应当创建一个新的合适的亨元对象。
5-客户端角色:本角色还需要自行存储所有亨元对象的外蕴状态。举个例子:比如围棋有300颗棋子,
用一般的设计模式,
创建一个类,
每个棋子都用一个对象的话
那就会非常麻烦,并且各自定义各自在棋盘的位置.....等等
而使用 亨元模式 来实现的话,
就用两个对象 :一个黑,一个白。
这样就可以了,至于棋子的方位不同,那只是对象的不同的外部表现形式或者说是外部状态。
这样三百多个对象就减到了两个对象。
享元模式以共享的方式高效地支持大量的细粒度对象,
说的再具体一些是将所有具有相同状态的对象指向同一个引用,
从而解决了系统在创建大量对象时所带来的内存压力。
享元模式应用较少,这里再举一个森林和树木的例子来说明这个模式的应用。
一片森林中有成千上万棵树木,如果每棵树都创建一个对象,那么内存中的对象数量相当庞大,更何况我们现实世界中还有成千上万个森林。4.亨元模式的好处
此模式最大限度地减少了尽可能与其他类似的对象多的数据共享内存的使用,
这是一种利用大量对象时,一个简单的重复表示将使用的内存接受的范围。
这个词来自于同名拳击重量级别。
通常的对象状态的某些部分可以共享,这很常见的结构,把外部数据并传递给了轻量级的对象时,暂时使用。
以上的这些例子 说明了亨元模式,以减少使用只加载必要的数据,内存来执行从一个大字体对象的某些紧迫任务到更小FontData(轻量级)对象。