Decorator pattern implementation

2020-02-23 03:22发布

问题:

Trying to implement the decorator pattern in C# from the code in the "Head First Design Patterns" book (written in Java).

I am just starting out with C# and am therefore still new to the syntax, so I am not sure why I can't get the commented line of code below to work.

Here is the first abstract-base class and its derived classes in the Decorator pattern:

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

The offending code is in the Cost() method of the Mocha class:

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

回答1:

Change new to override. Also, m_description should be protected.



回答2:

You have declared the Cost() method of Mocha as new instead of override. See here the difference: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-code-override-code-and-code-new-code.aspx



回答3:

This is how should your code look.

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