设计模式之享元模式

2022-03-29 10:06:44 浏览数 (1)

这节讲一下享元模式(Flyweight Pattern)。

在设计一个程序的时候,有时候我们会遇到构建大量重复实例的问题,比如一个五子棋游戏,每一个棋子都是一个对象,它们占据了很大的资源,但是这些对象实际上内部的差别很小,这种情况就催生了享元模式的形成。

享元(Flyweight)模式的定义:运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

它的主要优点是:相同对象只保存一份,这降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。 其主要缺点是:

  1. 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
  2. 读取享元模式的外部状态会使得运行时间稍微变长。

下面通过一段代码来演示一下享元模式:

代码语言: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;
    }
}

运行结果为:

享元对象共享出来的信息,存储在享元信息内部,并且不会随环境的改变而改变,外部对象(非享元对象)得以依赖的一个标记,随环境的改变而改变,不可共享。这就是享元模式。

本节到此结束...

0 人点赞