小编典典

用一个真实的例子来理解“装饰器模式”

all

我正在研究GOF中记录的 装饰器模式

请帮助我理解 装饰者模式 。有人可以举一个在现实世界中有用的用例示例吗?


阅读 63

收藏
2022-08-15

共1个答案

小编典典

装饰器模式实现了向任何对象动态添加职责的单一目标。

考虑一个比萨店的案例。在比萨店,他们将出售几种比萨品种,并且他们还将在菜单中提供浇头。现在想象这样一种情况,如果比萨店必须为比萨饼和配料的每种组合提供价格。即使有四种基本的比萨饼和
8 种不同的浇头,应用程序也会疯狂地维护所有这些比萨饼和浇头的具体组合。

装饰器模式来了。

根据装饰器模式,您将实现浇头作为装饰器,比萨饼将由这些浇头的装饰器装饰。实际上,每个顾客都想要他想要的浇头,最终的账单金额将由基础比萨饼和额外订购的浇头组成。每个浇头装饰师都会知道它正在装饰的比萨饼及其价格。GetPrice()Topping
对象的方法将返回比萨饼和浇头的累积价格。

编辑

这是上面解释的代码示例。

public abstract class BasePizza
{
    protected double myPrice;

    public virtual double GetPrice()
    {
        return this.myPrice;
    }
}

public abstract class ToppingsDecorator : BasePizza
{
    protected BasePizza pizza;
    public ToppingsDecorator(BasePizza pizzaToDecorate)
    {
        this.pizza = pizzaToDecorate;
    }

    public override double GetPrice()
    {
        return (this.pizza.GetPrice() + this.myPrice);
    }
}

class Program
{
    [STAThread]
    static void Main()
    {
        //Client-code
        Margherita pizza = new Margherita();
        Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());

        ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
        ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
        Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());

        MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
        Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());

        JalapenoTopping moreJalapeno = new JalapenoTopping(moreMushroom);
        Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());

        Console.ReadLine();
    }
}

public class Margherita : BasePizza
{
    public Margherita()
    {
        this.myPrice = 6.99;
    }
}

public class Gourmet : BasePizza
{
    public Gourmet()
    {
        this.myPrice = 7.49;
    }
}

public class ExtraCheeseTopping : ToppingsDecorator
{
    public ExtraCheeseTopping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 0.99;
    }
}

public class MushroomTopping : ToppingsDecorator
{
    public MushroomTopping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 1.49;
    }
}

public class JalapenoTopping : ToppingsDecorator
{
    public JalapenoTopping(BasePizza pizzaToDecorate)
        : base(pizzaToDecorate)
    {
        this.myPrice = 1.49;
    }
}
2022-08-15