享元模式(Flyweight Pattern)
当对象数量太多时,将导致运行代价过高,带来性能下降,内存溢出等问题。为了解决这一问题便诞生了享元模式。把其中具有相同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也成为细粒度对象。
使用场景:
当频繁地从数据源读取数据时,读出的内容存在重复,那么需要使用享元模式(Flyweight)来提高内存效率,Flyweight模式将节省更多空间,共享的Flyweight越多,空间节省越大。
优点:大大较少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分类出外部状态和内容状态,
而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
抽象享元:
/// <summary>
/// 抽象享元
/// </summary>
public interface IFlyWeight
{
//初始化属性
void Initialize(string Name);
}
具体享元:
/// <summary>
/// 具体享元
/// </summary>
public class ConcreteFlyweight : IFlyWeight
{
string name;
public void Initialize(string name)
{
this.name = name;
}
public void GetName()
{
Debug.Log(name);
}
}
享元工厂:
/// <summary>
/// 享元工厂
/// </summary>
public class FlyweightFactory
{
//和字典一样的用法,但它可以放入任何类型,支持多线程。速度比字典慢
public Hashtable hashTable = new Hashtable();
public ConcreteFlyweight GetFlyweight(string key)
{
if (!hashTable.ContainsKey(key))
{
hashTable.Add(key, new ConcreteFlyweight());
}
return hashTable[key] as ConcreteFlyweight;
}
}
运行测试:
void Start()
{
FlyweightFactory flyweightFactory = new FlyweightFactory();//新建一个享元工厂
ConcreteFlyweight flyWeight1 = flyweightFactory.GetFlyweight("A");//获取一个享元对象A
ConcreteFlyweight flyWeight2 = flyweightFactory.GetFlyweight("B");//获取一个享元对象B
flyWeight1.Initialize("A对象"); //初始化享元数值和属性
flyWeight2.Initialize("B对象");
flyWeight1.GetName(); //使用享元数值
flyWeight2.GetName();
//==========================
ConcreteFlyweight flyWeight3 = flyweightFactory.GetFlyweight("A"); //再次获取对象A
flyWeight3.GetName(); //使用享元数值
}
结果: