【问题标题】:Decorator pattern implementation装饰器模式实现
【发布时间】:2012-02-16 01:51:12
【问题描述】:

尝试根据“Head First Design Patterns”一书(用 Java 编写)中的代码在 C# 中实现装饰器模式。

我刚开始使用 C#,因此对语法还是很陌生,所以我不确定为什么我不能让下面注释的代码行工作。

这是装饰器模式中的第一个抽象基类及其派生类:

using System;

public abstract class Beverage
{
    private String m_description;

    // get a description of the beverage
    public virtual String Description { get { return m_description; } }

    // calculate cost of the beverage
    public abstract double Cost();
}

// HouseBlend coffee implements Beverage
public class HouseBlend : Beverage
{
    // Constructor
    public HouseBlend() { m_description = "House Blend"; }

    // calculate base cost of House Blend
    public override double Cost() { return 0.89; }
}

// DarkRoast coffee implements Beverage
public class DarkRoast : Beverage
{
    // Constructor
    public DarkRoast() { m_description = "Dark Roast"; }

    // calculate base cost of Dark Roast
    public override double Cost() { return 1.00; }
}

// Espresso coffee implements Beverage
public class Espresso : Beverage
{
    // Constructor
    public Espresso() { m_description = "Espresso"; }

    // calculate base cost of Espresso
    public override double Cost() { return 1.99; }
}

违规代码在 Mocha 类的 Cost() 方法中:

using System;

// abstract base class CondimentDecorator is-a Beverage
public abstract class CondimentDecorator : Beverage {}

// Mocha implements the CondimentDecorater
public class Mocha : CondimentDecorator
{
    // Condiment decorator has-a Beverage (recursion!)
    private Beverage m_beverage;

    // Constructor binds the object passed to member var
    public Mocha(Beverage beverage)
    {
        this.m_beverage = beverage;
    }

    // getter implements abstract class Description
    public override String Description
    {
        get
        {
            return m_beverage.Description + ", Mocha";
        }
    }

    // get the Cost of the condiment plus the base-cost
    // of the original beverage
    public new double Cost()               // ERROR: 'Mocha.Cost()' hides inherited
    {                                      // member 'Beverage.Cost()'
        return 0.20 + m_beverage.Cost();
    }
}

【问题讨论】:

标签: c# oop design-patterns inheritance decorator


【解决方案1】:

new 更改为override。另外,m_description 应该是protected

【讨论】:

  • 德普。将 m_description 声明为受保护而不是私有应该是不费吹灰之力...
  • 我建议将本地字段保持为私有并通过受保护的属性将其公开给继承者。
  • 不确定这将如何完成...我已经有一个用于设置和获取名为 Description 的 m_description 的属性列表,但我不确定如何使用它来访问 Cost() 方法饮料对象。
  • @Dylan:@Erik Dietrich 的意思如下:将m_description 保密。您可以通过向Beverage 添加一个构造函数来设置m_description,该构造函数采用string description 并将其分配给构造函数主体中的m_description。然后通过构造函数链接从每个派生类调用此构造函数。所以,对于Mocha,例如,`public Mocha() : base("Mocha") { }`.
【解决方案2】:

您已将 Mocha 的 Cost() 方法声明为 new 而不是覆盖。看这里的区别:http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-code-override-code-and-code-new-code.aspx

【讨论】:

  • 感谢您的解释;现在我看到了区别。
【解决方案3】:

你的代码应该是这样的。

public abstract class Beverage
{
    protected string m_description = "Unknown Beverage";

    public virtual string GetDescription()
    {
        return m_description;
    }

    public abstract double Cost();
}

public abstract class CondimentDecorator : Beverage
{
}

public class Espresso : Beverage
{
    public Espresso()
    {
        m_description = "Espresso";
    }

    public override double Cost()
    {
        return 1.99;
    }
}

public class HouseBlend : Beverage
{
    public HouseBlend()
    {
        m_description = "House Blend Coffe";
    }

    public override double Cost()
    {
        return 0.89;
    }
}

public class DarkRoast : Beverage
{
    public DarkRoast()
    {
        m_description = "Dark Roast";
    }

    public override double Cost()
    {
        return 0.99;
    }
}

public class Mocha : CondimentDecorator
{
    Beverage beverage;

    public Mocha(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string GetDescription()
    {
        return beverage.GetDescription() + ", Mocha";
    }

    public override double Cost()
    {
        return 0.20 + beverage.Cost();
    }
}

public class Soy : CondimentDecorator
{
    Beverage beverage;

    public Soy(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string GetDescription()
    {
        return beverage.GetDescription() + ", Soy";
    }

    public override double Cost()
    {
        return 0.15 + beverage.Cost();
    }
}

public class Whip : CondimentDecorator
{
    Beverage beverage;

    public Whip(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string GetDescription()
    {
        return beverage.GetDescription() + ", Whip";
    }

    public override double Cost()
    {
        return 0.10 + beverage.Cost();
    }
}

【讨论】:

    猜你喜欢
    • 2018-12-23
    • 2011-03-08
    • 1970-01-01
    • 2019-03-25
    • 2020-02-29
    • 2018-03-10
    • 2021-04-07
    • 1970-01-01
    • 2015-05-27
    相关资源
    最近更新 更多