意图
运用共享技术有效地支持大量细粒度的对象。典型的享元模式的例子为文书处理器中以图形结构来表示字符。一个做法是,每个字型有其字型外观, 字模 metrics, 和其它格式资讯,但这会使每个字符就耗用上千字节。取而代之的是,每个字符参照到一个共享字形物件,此物件会被其它有共同特质的字符所分享;只有每个字符(文件中或页面中)的位置才需要另外储存。以下程式用来解释上述的文件例子。这个例子用来解释享元模式利用只载立执行立即小任务所必需的资料,因而减少内存使用量。
适用性
1.一个应用程序使用了大量的对象。
2.完全由于使用大量的对象,造成很大的存储开销。
3.对象的大多数状态都可变为外部状态。
4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5.应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
结构图
// Flyweight
/* Notes:
* Useful patetn when you have a small(ish) number of objects that might be
* needed a very large number of times - with slightly differnt informaiton,
* that can be externalised outside those objects.
*/
namespace Flyweight_DesignPattern
{
using System;
using System.Collections;
class FlyweightFactory
{
private ArrayList pool = new ArrayList();
// the flyweightfactory can crete all entries in the pool at startup
// (if the pool is small, and it is likely all will be used), or as
// needed, if the pool si large and it is likely some will never be used
public FlyweightFactory()
{
pool.Add(new ConcreteEvenFlyweight());
pool.Add(new ConcreteUnevenFlyweight());
}
public Flyweight GetFlyweight(int key)
{
// here we would determine if the flyweight identified by key
// exists, and if so return it. If not, we would create it.
// As in this demo we have implementation all the possible
// flyweights we wish to use, we retrun the suitable one.
int i = key % 2;
return((Flyweight)pool[i]);
}
}
abstract class Flyweight
{
abstract public void DoOperation(int extrinsicState);
}
class UnsharedConcreteFlyweight : Flyweight
{
override public void DoOperation(int extrinsicState)
{
}
}
class ConcreteEvenFlyweight : Flyweight
{
override public void DoOperation(int extrinsicState)
{
Console.WriteLine("In ConcreteEvenFlyweight.DoOperation: {0}", extrinsicState);
}
}
class ConcreteUnevenFlyweight : Flyweight
{
override public void DoOperation(int extrinsicState)
{
Console.WriteLine("In ConcreteUnevenFlyweight.DoOperation: {0}", extrinsicState);
}
}
/// <summary>
/// Summary description for Client.
/// </summary>
public class Client
{
public static int Main(string[] args)
{
int[] data = {1,2,3,4,5,6,7,8};
FlyweightFactory f = new FlyweightFactory();
int extrinsicState = 3;
foreach (int i in data)
{
Flyweight flyweight = f.GetFlyweight(i);
flyweight.DoOperation(extrinsicState);
}
return 0;
}
}
}