Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单例模式与装饰器相结合_C#_Design Patterns - Fatal编程技术网

C# 单例模式与装饰器相结合

C# 单例模式与装饰器相结合,c#,design-patterns,C#,Design Patterns,附件是一个经典的装饰图案。我的问题是,您将如何修改下面的代码,以便可以在比萨饼上包装零个或每个配料中的一个 现在我可以上一堂Pepporini->香肠-->Pepporini-->披萨课,总成本高达10美元,Pepporini要收费两倍 我认为我不想使用责任链模式,因为顺序无关紧要,而且不是所有的浇头都被使用 多谢各位 namespace PizzaDecorator { public interface IPizza { double CalculateCost(); } publi

附件是一个经典的装饰图案。我的问题是,您将如何修改下面的代码,以便可以在比萨饼上包装零个或每个配料中的一个

现在我可以上一堂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;
    }  
}
}

我不会在这种情况下使用decorator模式。取而代之的是,我会让比萨饼装上一套:

public interface ITopping {
    double cost();
}

这套设备将保证不重复。现在,为了计算比萨饼的成本,你要把它的底价加到所有配料成本的总和上。在这种情况下,我不会使用装饰图案。取而代之的是,我会让比萨饼装上一套:

public interface ITopping {
    double cost();
}

这套设备将保证不重复。现在,要计算一个比萨饼的成本,你需要将它的基价加到所有浇头成本的总和中,我将创建一个有价格的
浇头
类,使你的
比萨饼
类支持多个浇头。然后根据添加的每种配料计算价格,例如:

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;
        }
        return total;
    }
}

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; }
}

我将创建一个
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;
        }
        return total;
    }
}

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; }
}

不,我隐藏了“真实”的应用程序,是为了我的工作,但这不仅仅是家庭作业,这实际上带来了收入:)当你开始以模式思考时,这表明你做得太过分了。不,我隐藏了“真实”的应用程序,是为了我的工作,但这不仅仅是家庭作业,这实际上带来了收益:)当你开始以模式思考时,这表明你做得太过分了。+1我想提出同样的建议,
配料
不是
IPizzas
,应该由披萨来引用,而不是相反。(这可能仅仅是因为Mike“隐藏了真实的应用程序”,在这种情况下,我们需要查看真实的类层次结构以进一步帮助您)。ITopping的目的是什么?我真的不认为有必要将上述设计分为子类
Topping
。我想一个简单的包含价格/描述的
Topping
类就足够了。+1我想提出同样的建议,
Toppings
不是
IPizzas
,应该被比萨饼引用,而不是相反。(这可能仅仅是因为Mike“隐藏了真实的应用程序”,在这种情况下,我们需要查看真实的类层次结构以进一步帮助您)。ITopping的目的是什么?我真的不认为有必要将上述设计分为子类
Topping
。我想一个简单的
Topping
类,包含一个price/description就足够了。这就是我的建议。在比萨饼的上下文中,我觉得非常合乎逻辑。Mike说他“隐藏了真正的应用程序”,所以他可能实际上需要为每个“顶部”单独、更复杂的逻辑,而不仅仅是价格。@BlueRaja:我认为Mike所指的隐藏了真正的应用程序,而不是提供真正的代码示例。他用了披萨和浇头的关系,这就是我的建议。在比萨饼的上下文中,我觉得非常合乎逻辑。Mike说他“隐藏了真正的应用程序”,所以他可能实际上需要为每个“顶部”单独、更复杂的逻辑,而不仅仅是价格。@BlueRaja:我认为Mike所指的隐藏了真正的应用程序,而不是提供真正的代码示例。他用披萨/浇头的关系来代替。