真是精彩的讨论!时隔两年我在再来回复有点过时。不过jdon真是个好社区!

我是比较草根的,开发经验有10多年了。相信大道至简这句话。

现在正在正规化,专业问题我就暂时不发言了。呵呵。这里指出一个可能的问题:

“fine-grained 的翻译 应当是 “均匀粒度”,也就是字母(对象)出现的频率相差不大。”

这句话不对。fine-grained是精细的意思。也就是我们电子产品(比如收音机)中常说的细调、微调的意思。
grained的意思是磨粉的意思。也就是这个是磨得比较细的精制面粉。用在OO上面,我的理解是这个方法提供
了对对象的精细控制,通俗说,就是很多属性可以让用的人控制对象的方方面面。

"Flyweight是为解决包含相同信息多个实例反复创建的性能开销,是一个提高性能的模式,常见EJB等J2EE中使用的Object cache和Object Pool都属于这种Flyweight具体应用表现。"

I agree banq with this...

好好,Jdon的帖子就是那么难过时。

个人感觉还是oxygen说的在理,因为即使如banq老师的解释,Flyweight是抽象的模式而cache和pool是具体的实现,双方无法比较,但即使把cache和pool放在继承Flyweight的角度来谈也是有问题的,因为很难相信它们是继承关系:

1) oxygen强调了Flyweight的一个重要特性就是Sharing,这个无论是cache还是pool通常都不具备的。周星驰可以从千百个小孩中选出一个像自己小时候的孩子(居然是个女孩)来演父子戏,但那个小孩不可能有资格继承周星驰,长得像是没用的,关键是DNA这个关键内涵不匹配。
2) 用cache和pool来实现Flyweight会相当的别扭,一个由pool提供的对象在returnObject()之类方法归池之前是独享的,这根本就是同Flyweight的思想背道而驰了,继承更是无从谈起。
3) 虽然双方都强调“复用”,但以文字排版为例就知道,实际上Flyweight更强调一个空间中延展的复用,它可能是同一瞬间的,但pool不行,要复用对象A,请排队,否则,给你对象B,它们长得一模一样,您凑合着用吧。

当然,毕竟双方一个是抽象一个是具象,非要设计一个pool来实现Flyweight也不是不可以,只是削足适履罢了。

这个老帖子,谈得较深入,我围绕其中的矛盾焦点,说说自己的理解。

Flyweight 对对象的内部状态进行共享,只为每种内部状态创建一个实例,实现方式可用单例模式。

Object pool也可运用单例模式,但是不是单例Object的内部状态,而是整个Object对象(比如String pool)。从单例模式的角度来看,Object pool与flyweight的实现手段相似,但共享的“粒度”有所不同,一个是内部状态-“局部”,一个是整个对象-“整体”。此外,常见的连接池pool保存着多个连接,这个可以理解为单例模式的推广:多例模式。

Object Cache 提升访问性能,flyweight也有此效果,但实现“手段”不同,Cache是对对象进行拷贝放在可以较快访问的地方,flyweight共享已创建实例对象,不必重复创建。Cache通过拷贝“增加”实例的数目来提升性能(可以较快地访问这些拷贝),flyweight通过共享“减少”(单例)实例的数目来提升性能(内存和创建时间的
减少)。

从访问性能的提高的这个角度看,Object Cache的意义更像Proxy, 毕竟flyweight的本意是减少内存的开销,flyweight从字面上看有“身轻如燕”之意,对象的weight之轻可以fly起来。至于“减少反复创建的性能开销”只是副作用,不是第一目标,而且这个副作用是由创建型模式来带来的。

flyweight因为“共享”提高了“性能”,于是banq从“共享”角度将Object pool归为其一种具体运用(虽然都用了单例没模式,但共享的“粒度”不同,模式的“分类意义”不同,一个是结构型,一个是创建型);从“性能”角度将Object cache归为其一种具体运用(但“手段”不同,“第一目标”也不同,一个是增加拷贝降低访问“运算”开销,一个减少实例的创建,即共享降低“内存”的开销。)。个人以为,banq这里对这几样东西的归类略显自由了一点。

flyweight是抽象模式,object pool/cache是具体运用,直接比较并不妥。可以对object pool/cache进行抽象后,再与flyweight比较。下面是简单的个人总结:

flyweight是结构型模式,对内部状态使用了单例模式;object pool是创建型--单例(多例)模式的一种运用;从object cache以提高访问性能来为第一目标的角度来看,与proxy的用途之一极其相似,只是实现手段与常规的proxy相差太多,所以这里只能取其意,忘其形,将其划分为结构型模式proxy的一种具体运用。

顶楼主以及楼上,不赞成一下banq。

1.flyweight和object pool既不是具体与抽象的关系,也不是一件事情的两种解决办法。
2.object pool是多例模式的实现。
3.多例模式和flyweight是可以平行讨论的内容,它们都是模式,在不同的场景下解决一些特定的问题。

场景:公司总部在单位附近租宿舍
1.Cache:
项目很棘手,把骨干员工调到总部来,安排在宿舍,随叫随到;
目的:访问速度快。
2.Pool:
项目结束后,房子不要退,分公司的员工轮流来培训,就安排在宿舍;
目的:减少租赁手续。
3.FlyWeight:
宿舍是四人间,四个员工共用一个宿舍;
目的:节省租金。