1、结构图
2、代码
/*************************************************************
* 意图:运用共享技术有效地支持大量细粒度的对象。
*
* 适用性:
* 1、一个应用程序使用了大量的对象。
* 2、完全由于使用大量的对象,造成很大的存储开销。
* 3、对象的大多数状态都可变为外部状态。
* 4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
* 5、应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,
* 对于概念上明显有别的对象,标识测试将返回真值。
* 协作:
* 1、Flyweight执行时所需的状态必定是内部的或外部的。内部状态存储在ConcreteFlyweight
* 对象之中;而外部对象则由Client对象存储或计算。当用户调用Flyweight对象的操作时,
* 将该状态传递给它。
* 2、用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到
* ConcreteFlyweight对象,这可以保证对它们适当地进行共享。
*
* 作者:董怀信
* 日期:2009-06-04
* **********************************************************/
using System;
namespace DesignPattern.StructuralPattern.Flyweight
{
/// <summary>
/// 描述一个接口,通过这个接口Flyweight可以接受并作用于外部状态。
/// </summary>
public interface Flyweight
{
void Operation(string extrinsicState);
}
/// <summary>
/// 实现Flyweight接口,并为内部状态(如果有的话)增加存储空间。
/// ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是
/// 内部的;即,它必须独立于ConcreteFlyweight对象的场景。
/// </summary>
public class ConcreteFlyweight:Flyweight
{
private string m_intrinsicState;
public ConcreteFlyweight(string intrinsicState)
{
m_intrinsicState = intrinsicState;
}
private string m_extrinsicState;
#region Flyweight Members
public void Operation(string extrinsicState)
{
m_extrinsicState = extrinsicState;
Console.WriteLine("ConcreteFlyweight:Operation;");
Console.WriteLine("intrinsicState:" + m_intrinsicState);
Console.WriteLine("extrinsicState:" + extrinsicState);
}
#endregion
}
/// <summary>
/// 并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但
/// 它并不强制共享。在Flyweight对象结构的某些层次,UnsharedConcreteFlyweight
/// 对象通常将ConcreteFlyweight对象作为子节点。
/// </summary>
public class UnsharedConcreteFlyweight:Flyweight
{
private List<string> m_allState;
private ConcreteFlyweight m_flyweight;
public UnsharedConcreteFlyweight(string intrinsicState)
{
m_flyweight = new ConcreteFlyweight(intrinsicState);
m_allState = new List<string>();
}
#region Flyweight Members
public void Operation(string extrinsicState)
{
if (!m_allState.Contains(extrinsicState))
{
m_allState.Add(extrinsicState);
}
Console.WriteLine("UnsharedConcreteFlyweight:Operation;");
m_flyweight.Operation(extrinsicState);
Console.WriteLine("extrinsicState:" + extrinsicState.ToString());
}
#endregion
}
[Flags]
public enum ColorEnum
{
White = 1,
Black = 2,
All = White|Black
}
/// <summary>
/// 创建并管理Flyweight对象。
/// 确保合理地共享Flyweight。当用户请求一个Flyweight时,FlyweightFactory对象
/// 提供一个已创建的实例或者创建一个(如果不存在的话)。
/// </summary>
public class FlyweightFactory
{
private static Dictionary<ColorEnum, Flyweight> m_flyweightDict;
private static FlyweightFactory m_instance;
private static object m_synObj = new object();
private FlyweightFactory()
{
m_flyweightDict = new Dictionary<ColorEnum, Flyweight>();
m_flyweightDict.Add(ColorEnum.White, new ConcreteFlyweight("White"));
m_flyweightDict.Add(ColorEnum.Black, new ConcreteFlyweight("Black"));
m_flyweightDict.Add(ColorEnum.All, new UnsharedConcreteFlyweight("All"));
}
public static FlyweightFactory GetInstance()
{
if(m_instance == null)
{
lock (m_synObj)
{
if (m_instance == null)
{
m_instance = new FlyweightFactory();
}
}
}
return m_instance;
}
public Flyweight GetFlyweight(ColorEnum key)
{
if (!m_flyweightDict.ContainsKey(key))
{
m_flyweightDict.Add(key,new ConcreteFlyweight(key.ToString()));
}
return m_flyweightDict[key];
}
}
/// <summary>
/// 维持一个对Flyweight待引用。
/// 计算或存储一个(多个)Flyweight的外部状态。
/// </summary>
public class Client
{
public void Test()
{
Flyweight flyweight1 = FlyweightFactory.GetInstance().GetFlyweight(ColorEnum.Black);
flyweight1.Operation("Location 1,2");
flyweight1.Operation("Location 3,4");
Flyweight flyweight2 = FlyweightFactory.GetInstance().GetFlyweight(ColorEnum.White);
flyweight2.Operation("Location 5,3");
flyweight2.Operation("Location 9,1");
}
}
}