2012-01-22 24 views
12

Se intentó implementar el patrón de decorador en C# a partir del código del libro "Modelos de diseño de Head First" (escrito en Java).Implementación del patrón de decorador

Estoy empezando con C# y, por lo tanto, soy nuevo en la sintaxis, por lo que no estoy seguro de por qué no puedo hacer funcionar la línea de código comentada a continuación.

Aquí es la primera clase abstracta-base y sus clases derivadas en el patrón 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; } 
} 

El código erróneo es en el método de costo() de la clase 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(); 
    } 
} 
+11

FYI aunque el libro utiliza Java del [página web del libro] (http://headfirstlabs.com/books/hfdp/) enlaces a [código de ejemplo en C#] (http://www.msquaredweb.com/ DesignPatterns/HeadFirstDesignPatternsInCSharp.zip) y C++. –

+0

Bueno saber. Lo comprobaré – dtg

Respuesta

11

Cambie new a override. Además, m_description debe ser protected.

+0

Derp. Declarar m_description como protected en lugar de private debería haber sido una obviedad ... – dtg

+0

Aconsejaría mantener el campo local como privado y exponerlo a los herederos a través de una propiedad protegida. –

+0

No estoy seguro de cómo se haría esto ... Ya tengo una lista de propiedades para configurar y obtener m_description llamada Descripción, pero no estoy seguro de cómo se usaría para acceder al método Cost() del objeto de bebida. – dtg

1

Así es como debe verse su código.

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