这节讲一下享元模式(Flyweight Pattern)。
在设计一个程序的时候,有时候我们会遇到构建大量重复实例的问题,比如一个五子棋游戏,每一个棋子都是一个对象,它们占据了很大的资源,但是这些对象实际上内部的差别很小,这种情况就催生了享元模式的形成。
享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
它的主要优点是:相同对象只保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。 其主要缺点是:
- 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
- 读取享元模式的外部状态会使得运行时间稍微变长。
下面通过一段代码来演示一下享元模式:
代码语言:javascript复制class Program
{
static void Main(string[] args)
{
FlyweightFactory flyweightFactory = new FlyweightFactory();
IFlyweight black1 = flyweightFactory.GetFlyweight("黑键");
IFlyweight black2 = flyweightFactory.GetFlyweight("黑键");
IFlyweight wirte1 = flyweightFactory.GetFlyweight("白键");
IFlyweight wirte2 = flyweightFactory.GetFlyweight("白键");
black1.operation(new UnFlyweightObj("1:2"));
black2.operation(new UnFlyweightObj("10:20"));
wirte1.operation(new UnFlyweightObj("100:200"));
wirte2.operation(new UnFlyweightObj("1000:2000"));
}
}
/// <summary>
/// 非享元角色(也就是享元对象中的区别部分)
/// </summary>
class UnFlyweightObj
{
// 保存每个对象的个性化信息
public string Info { get; set; }
public UnFlyweightObj(string info)
{
this.Info = info;
}
}
//抽象享元角色
interface IFlyweight
{
void operation(UnFlyweightObj state);
}
/// <summary>
/// 具体享元角色
/// </summary>
class Flyweight : IFlyweight
{
private string key;
public Flyweight(string key)
{
this.key = key;
Console.WriteLine($"具体享元{key}被创建");
}
public void operation(UnFlyweightObj state)
{
Console.WriteLine($"具体享元{key}被调用");
Console.WriteLine($"非享元信息是{state.Info}");
}
}
/// <summary>
/// 享元角色工厂
/// </summary>
class FlyweightFactory
{
//存放每个享元对象
private Dictionary<string, IFlyweight> flyweigths = new Dictionary<string, IFlyweight>();
public IFlyweight GetFlyweight(string key)
{
IFlyweight flyweight =null;
bool result = flyweigths.TryGetValue(key, out flyweight);
if (result)
{
Console.WriteLine($"具体享元{key}已经存在,该对象已被复用");
}
else
{
flyweight = new Flyweight(key);
flyweigths.Add(key,flyweight);
}
return flyweight;
}
}
运行结果为:
享元对象共享出来的信息,存储在享元信息内部,并且不会随环境的改变而改变,外部对象(非享元对象)得以依赖的一个标记,随环境的改变而改变,不可共享。这就是享元模式。
本节到此结束...