代码之家  ›  专栏  ›  技术社区  ›  Mike

单例模式与装饰器结合

  •  0
  • Mike  · 技术社区  · 14 年前

    附件是一个经典的装饰图案。我的问题是你如何修改下面的代码,这样你就可以在披萨上包上每一个馅饼的0或1个馅饼

    现在,我可以吃一个比萨饼类的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 回复  |  直到 14 年前
        1
  •  5
  •   James    14 年前

    我会创造一个 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
    
        2
  •  1
  •   Asaf David    14 年前

    在这种情况下,我不会使用decorator模式。取而代之的是,我要一份比萨饼,上面有一套图片:

    public interface ITopping {
        double cost();
    }
    

    这一套保证不会重复。现在,要计算披萨的成本,你要把它的基价加在所有配料成本的总和上