Реализация шаблона декоратора - PullRequest
13 голосов
/ 22 января 2012

Попытка реализовать шаблон декоратора в C # из кода в книге «Head First Design Patterns» (написана на Java).

Я только начинаю с C # и поэтому все еще плохо знаком с синтаксисом, поэтому я не уверен, почему я не могу заставить закомментированную строку кода ниже работать.

Вот первый абстрактный базовый класс и его производные классы в шаблоне Decorator:

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

Код ошибки в методе Cost () класса Mocha:

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

Ответы [ 3 ]

12 голосов
/ 22 января 2012

Измените new на override. Кроме того, m_description должно быть protected.

7 голосов
/ 22 января 2012

Вы объявили метод Cost () для Mocha как новый вместо переопределения.Смотрите здесь разницу: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-code-override-code-and-code-new-code.aspx

1 голос
/ 16 февраля 2013

Вот так должен выглядеть ваш код.

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