设计模式(11)享元模式

模式介绍

享元模式用于创建许多小的、相关的对象,而无需为此调用大量开销工作,从而提高性能和可维护性。
享元模式允许对象的许多实例共享它们的内在状态,从而减少与创建它们相关的成本。

示例

我们以Slider(一种类似汉堡的食物)为例。

抽象的享元类

/// <summary>
/// The Flyweight class
/// </summary>
abstract class Slider
{
    protected string Name;
    protected string Cheese;
    protected string Toppings;
    protected decimal Price;

    public abstract void Display(int orderTotal);
}

具体的享元类

/// <summary>
/// A  ConcreteFlyweight class
/// </summary>
class BaconMaster : Slider
{
    public BaconMaster()
    {
        Name = "Bacon Master";
        Cheese = "American";
        Toppings = "lots of bacon";
        Price = 2.39m;
    }

    public override void Display(int orderTotal)
    {
        Console.WriteLine("Slider #" + orderTotal + ": " + Name + " - topped with " + Cheese + " cheese and " + Toppings + "! $" + Price.ToString());
    }
}

/// <summary>
/// A ConcreteFlyweight class
/// </summary>
class VeggieSlider : Slider
{
    public VeggieSlider()
    {
        Name = "Veggie Slider";
        Cheese = "Swiss";
        Toppings = "lettuce, onion, tomato, and pickles";
        Price = 1.99m;
    }

    public override void Display(int orderTotal)
    {
        Console.WriteLine("Slider #" + orderTotal + ": " + Name + " - topped with " + Cheese + " cheese and " + Toppings + "! $" + Price.ToString());
    }

}

/// <summary>
/// A ConcreteFlyweight class
/// </summary>
class BBQKing : Slider
{
    public BBQKing()
    {
        Name = "BBQ King";
        Cheese = "American";
        Toppings = "Onion rings, lettuce, and BBQ sauce";
        Price = 2.49m;
    }

    public override void Display(int orderTotal)
    {
        Console.WriteLine("Slider #" + orderTotal + ": " + Name + " - topped with " + Cheese + " cheese and " + Toppings + "! $" + Price.ToString());
    }
}

工厂类,实例具体的享元类

/// <summary>
/// The FlyweightFactory class
/// </summary>
class SliderFactory
{
    private Dictionary<char, Slider> _sliders =
        new Dictionary<char, Slider>();

    public Slider GetSlider(char key)
    {
        Slider slider = null;
        if (_sliders.ContainsKey(key)) //If we've already created one of the requested type of slider, just use that.
        {
            slider = _sliders[key];
        }
        else //Otherwise, create a brand new instance of the slider.
        {
            switch (key)
            {
                case 'B': slider = new BaconMaster(); break;
                case 'V': slider = new VeggieSlider(); break;
                case 'Q': slider = new BBQKing(); break;
            }
            _sliders.Add(key, slider);
        }
        return slider;
    }
}

客户端调用

static void Main(string[] args)
{
    // Build a slider order using patron's input
    Console.WriteLine("Please enter your slider order (use characters B, V, Z with no spaces):");
    var order = Console.ReadLine();
    char[] chars = order.ToCharArray();

    SliderFactory factory = new SliderFactory();

    int orderTotal = 0;

    //Get the slider from the factory
    foreach (char c in chars)
    {
        orderTotal++;
        Slider character = factory.GetSlider(c);
        character.Display(orderTotal);
    }

    Console.ReadKey();
}

总结

享元模式通过从一小组“模板”对象中创建大量对象来提高性能,这些对象与所有其他实例相同或非常相似。

源代码

https://github.com/exceptionnotfound/DesignPatterns/tree/master/Flyweight

原文

https://www.exceptionnotfound.net/flyweight-the-daily-design-pattern/