c# - 装饰模式问题C#/java

标签 c# java design-patterns decorator

我在看 this维基百科文章,无法理解它到底是如何工作的。有点沮丧不能仅仅通过查看代码来理解代码,我决定将代码移植到 c#(我是 .net,对不起大家 :))。只需要做一些小的修改(继承和扩展,super 的基础等)并运行应用程序。令我惊讶的是,我得到了以下输出:

Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee
Cost: 1 Ingredient: Coffee

只是好奇,任何 Java 开发人员都可以告诉我这里有什么不同以及为什么维基百科示例有效(当然,如果它确实像他们所说的那样有效)。

    namespace ConsoleApplication1
{
 class Program
 {
  static void Main(string[] args)
  {

  Coffee sampleCoffee = new SimpleCoffee();
  Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());

        sampleCoffee = new Milk(sampleCoffee);
        Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());

        sampleCoffee = new Sprinkles(sampleCoffee);
        Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());

        sampleCoffee = new Whip(sampleCoffee);
        Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient());

   Console.ReadKey();

  }
 }



//The Coffee Interface defines the functionality of Coffee implemented by decorator
public interface Coffee
{

    double getCost(); // returns the cost of coffee

    String getIngredient(); //returns the ingredients mixed with coffee
}

//implementation of simple coffee without any extra ingredients
public class SimpleCoffee : Coffee
{

    double cost;
    String ingredient;

    public SimpleCoffee()
    {
        cost = 1;
        ingredient = "Coffee";
    }

    public double getCost()
    {
        return cost;
    }

    public String getIngredient()
    {
        return ingredient;
    }
}



//abstract decorator class - note that it implements coffee interface
abstract public class CoffeeDecorator : Coffee
{

    protected Coffee decoratedCoffee;
    protected String ingredientSeparator;

    public CoffeeDecorator(Coffee decoratedCoffee)
    {
        this.decoratedCoffee = decoratedCoffee;
        ingredientSeparator = ", ";
    }

 public CoffeeDecorator()
 {

 }

    public double getCost() //note it implements the getCost function defined in interface Coffee
    {
        return decoratedCoffee.getCost();
    }

    public String getIngredient()
    {
        return decoratedCoffee.getIngredient();
    }
}

//Decorator Milk that mixes milk with coffee
//note it extends CoffeeDecorator
public class Milk : CoffeeDecorator
{

    double cost;
    String ingredient;

    public Milk(Coffee decoratedCoffee) : base(decoratedCoffee)
    {
        cost = 0.5;
        ingredient = "Milk";
    }

    public double getCost()
    {
        return base.getCost() + cost;
    }

    public String getIngredient()
    {
        return base.getIngredient() + base.ingredientSeparator + ingredient;
    }
}

//Decorator Whip that mixes whip with coffee
//note it extends CoffeeDecorator
public class Whip : CoffeeDecorator
{

    double cost;
    String ingredient;

 public Whip(Coffee decoratedCoffee)
  : base(decoratedCoffee)
    {
        cost = 0.7;
        ingredient = "Whip";
    }

    public double getCost()
    {
        return base.getCost() + cost;
    }

    public String getIngredient()
    {
        return base.getIngredient() + base.ingredientSeparator + ingredient;
    }
}

//Decorator Sprinkles that mixes sprinkles with coffee
//note it extends CoffeeDecorator
public class Sprinkles : CoffeeDecorator
{

    double cost;
    String ingredient;

    public Sprinkles(Coffee decoratedCoffee) : base(decoratedCoffee)
    {

        cost = 0.2;
        ingredient = "Sprinkles";
    }

    public double getCost()
    {
  return base.getCost() + cost;
    }

    public String getIngredient()
    {
  return base.getIngredient() + base.ingredientSeparator + ingredient;
    }
}

}

最佳答案

是的 - 默认情况下方法在 Java 中是虚拟的,但在 C# 中不是。

您应该在编译代码时收到警告,谈论“new”修饰符。那应该给了你一个线索。目前,您的 Milk(等)方法正在隐藏隐藏那些在 CoffeeDecorator 中的方法 - 它们没有被多态调用.

您需要使用 virtual 修饰符使 CoffeeDecorator 方法成为虚拟方法,然后在 Milk (等)中显式覆盖它们override 修饰符。

// In CoffeeDecorator
public virtual double getCost()
{
    return decoratedCoffee.getCost();
}

// In Milk
public override double getCost()
{
    return base.getCost() + cost;
}

关于c# - 装饰模式问题C#/java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4333462/

相关文章:

c# - MVC View 中的 Html 元素为空

c# - 使用 XSP4 在 Monodevelop 中调试 ASP.NET MVC 应用程序

java - OpenCV改变矩形中的RGB参数

java - Java 自然语言处理 (NLP)

java - 使用 BigDecimal 的小数点后的最大位数

design-patterns - TDD 最终会得到纯值对象和纯操纵器/ Controller 吗?

javascript - 如何通过模块模式制作子模块

c# - LDAPConnection 通过 NT 帐户检索用户

c# - WCF服务如何检测客户端断开连接

asp.net-mvc - 与使用 HTML + Javascript + Services 应用程序相比,使用传统 MVC 框架有哪些优势?