http://oldboy-bj.taobao.com/

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

http://www.35java.com/zhibo/forum.php?mod=viewthread&tid=276&extra=page%3D2

 

Gof 的书中指出,Flyweight的目的在于运用共享技术,使得一些细粒度的物件可以共享。

Flyweight在牛津字典中的解释是"boxer of the lightest class"。意思是特轻量级拳击手?其实应该是取"thelightestclass"这部份的解释,一个特轻量级类别,这个类别所产生的物件可以共用在每一个场合(context),并依场合资讯表现物件外观。

在书中所举出的例子是文档编辑器中的字元物件,若每个字元物件会包括字元、大小、字型等等不同的资讯,想想一篇文章中可能出现多少字元,如果我们为每一个字元都使用一个物件来完整描述有关于它的讯息,那么一篇文字中将会耗用多少的记忆体?!字元本身应可以共享,而大小、字型等等不同的资讯再分别设定。

考虑数量多且性质相近的物件时,将该物件的资讯分为两个部份:内部状态(intrinsic)与外部状态(extrinsic)。以上例来说,字元属于内部状态,而大小、字型等等不同的资讯属于外部状态。

更详细一些来说明,内部状态是物件可共享的讯息部份,例如在绘制一个英文字串时,重覆的字元部份为内部状态,像是 "ABC isBAC",其中A、B、C的字元资讯部份不必直接储存于字元物件中,它是属于可以共享的部份,可以将这些可以重复使用的字元储存在FlyweightPool中。

外部状态是物件依赖的一个场景(context),例如绘制字元时的字型资讯、位置资讯等等,绘制一个字元时,先从Flyweight Pool中找出共享的Flyweight,然后从场景中查找对应的绘制资讯(字型、大小、位置等)。

其实任何学过Java的人就一定使用过Java中运用Flyweight模式的好处,要知道,如果您在程式中使用下面的方式来宣告,则实际上是指向同一个字串物件:
String str1 = "flyweight";
String str2 = "flyweight";
System.out.println(str1 == str2);


程式的执行结果会显示True,在Java中,会维护一个String Pool,对于一些可以共享的字串物件,会先在StringPool中查找是否存在相同的String内容(字元相同),如果有就直接传回,而不是直接创造一个新的String物件,以减少记忆体的耗用。

再来个一看例子,String的intern()方法,我们来看看它的API说明的节录:
Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

Whenthe intern method is invoked, if the pool already contains a stringequal to this String object as determined by the equals(Object) method,then the string from the pool is returned. Otherwise, this Stringobject is added to the pool and a reference to this String object isreturned.


这段话其实已说明了Flyweight模式的运作方式,用个实例来说明会更清楚:

posted on 2011-01-06 15:56  老男孩咖啡  阅读(144)  评论(0编辑  收藏  举报