Singleton Pattern与装饰器相结合

时间:2010-04-20 20:55:57

标签: c# design-patterns

附件是一个经典的装饰模式。我的问题是你如何修改下面的代码,以便你可以将每个顶部的零个或一个包裹到披萨上

现在我可以有一个Pepporini - >香肠 - > Pepporini - >比萨级的总费用高达10美元,Pepporini的费用是两倍。

我认为我不想使用责任链模式,因为订单无关紧要并且并非使用所有配料?

谢谢

namespace PizzaDecorator
{
public interface IPizza
{
    double CalculateCost();
}

public class Pizza: IPizza
{
    public Pizza()
    {
    }

    public double CalculateCost()
    {
        return 8.00;
    }

}

public abstract class Topping : IPizza
{
    protected IPizza _pizzaItem;

    public Topping(IPizza pizzaItem)
    {
        this._pizzaItem = pizzaItem;
    }

    public abstract double CalculateCost();

}

public class Pepporini : Topping
{
    public Pepporini(IPizza pizzaItem)
        : base(pizzaItem) 
    {   
    }

    public override  double CalculateCost()
    {
        return this._pizzaItem.CalculateCost() + 0.50;
    }


}

public class Sausage : Topping
{
    public Sausage(IPizza pizzaItem)
        : base(pizzaItem)
    {
    }


    public override double CalculateCost()
    {
        return this._pizzaItem.CalculateCost() + 1.00;
    }
}

public class Onions : Topping
{
    public Onions(IPizza pizzaItem)
        : base(pizzaItem)
    {
    }

    public override double CalculateCost()
    {
        return this._pizzaItem.CalculateCost() + .25;
    }  
}
}

2 个答案:

答案 0 :(得分:5)

我会创建一个Topping类,它会有一个价格,让你的Pizza类支持多个顶部。然后根据添加的每个顶部计算价格,例如

public interface IPizza
{
    double CalculateCost();
}

public class Pizza : IPizza
{
    private List<Topping> toppings = new List<Topping>();
    private double stdCost;

    public Pizza(double cost)
    {
        // this would be the standard cost of the pizza (before any toppings have been added)
        stdCost = cost;
    }

    public Pizza(IList<Topping> toppings)
    {
        this.toppings.AddRange(toppings);
    }

    public void AddTopping(Topping topping)
    {
        this.toppings.Add(topping);
    }

    public void RemoveTopping(Topping topping)
    {
        this.toppings.Remove(topping);
    }

    public double CalculateCost()
    {
        var total = stdCost;
        foreach (var t in toppings)
        {
            total += t.Price;
        }
    }
}

public class Topping
{
    public Topping(string description, double price)
    {
        Description = description;
        Price = price;
    }

    public double Price { get; private set; }
    public string Description { get; private set; }
}

用法

IPizza p = new Pizza(5.00);
p.AddTopping(new Topping("Pepperoni", 0.50));
p.AddTopping(new Topping("Sausage", 0.50));
var charge = p.CalculateCost(); // charge = 6.00

答案 1 :(得分:1)

我不会在这种情况下使用装饰模式。相反,我有披萨拿着一套ITopping:

public interface ITopping {
    double cost();
}

该套装将保证不重复。现在,要计算比萨饼的成本,你可以将它的基本价格加到所有浇头成本的总和上