这个老帖子,谈得较深入,我围绕其中的矛盾焦点,说说自己的理解。
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的一种具体运用。