Узор Singleton в сочетании с декоратором - PullRequest
0 голосов
/ 21 апреля 2010

Прилагается классический шаблон Decorator. Мой вопрос заключается в том, как бы вы изменили приведенный ниже код, чтобы вы могли обернуть ноль или одну из каждой добавки в пиццу

Прямо сейчас у меня может быть 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 ]

5 голосов
/ 21 апреля 2010

Я бы создал класс 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 голос
/ 21 апреля 2010

Я бы не использовал шаблон декоратора для этой ситуации. вместо этого я бы взял пиццу с набором ITopping:

public interface ITopping {
    double cost();
}

комплект гарантирует отсутствие дубликатов. Теперь, чтобы рассчитать стоимость пиццы, вы добавите ее базовую цену к сумме всех начальных расходов

...