Implementasi pola dekorator

Mencoba mengimplementasikan pola dekorator dalam C# dari kode di buku "Head First Design Patterns" (ditulis dalam Java).

Saya baru memulai dengan C# dan oleh karena itu saya masih baru dalam sintaksisnya, jadi saya tidak yakin mengapa saya tidak dapat membuat baris kode yang dikomentari di bawah ini berfungsi.

Berikut adalah kelas berbasis abstrak pertama dan kelas turunannya dalam pola Dekorator:

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

Kode yang melanggar ada dalam metode Cost() kelas 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();
    }
}

person dtg    schedule 22.01.2012    source sumber
comment
FYI meskipun buku ini menggunakan Java, tautan situs web buku ke contoh kode dalam C# dan C++.   -  person Ahmad Mageed    schedule 22.01.2012


Jawaban (3)


Ubah new menjadi override. Selain itu, m_description seharusnya menjadi protected.

person jason    schedule 22.01.2012
comment
Derp. Mendeklarasikan m_description sebagai dilindungi alih-alih pribadi seharusnya tidak perlu dipikirkan lagi... - person dtg; 22.01.2012
comment
Saya akan menyarankan agar bidang lokal tetap bersifat pribadi dan memaparkannya kepada pewaris melalui properti yang dilindungi. - person Erik Dietrich; 22.01.2012
comment
Tidak yakin bagaimana ini akan dilakukan... Saya sudah memiliki daftar properti untuk mengatur dan mendapatkan m_description yang disebut Deskripsi, tapi saya tidak yakin bagaimana ini akan digunakan untuk mengakses metode Cost() dari objek minuman. - person dtg; 22.01.2012
comment
@Dylan: Apa yang dikatakan @Erik Dietrich adalah sebagai berikut: jaga m_description sebagai pribadi. Anda dapat mengatur m_description dengan menambahkan konstruktor ke Beverage yang mengambil string description dan menetapkannya ke m_description di badan konstruktor. Kemudian panggil konstruktor ini dari masing-masing kelas turunan dengan rangkaian konstruktor. Jadi, untuk Mocha, misalnya,` public Mocha() : base(Mocha) { }`. - person jason; 23.01.2012

Anda telah mendeklarasikan metode Cost() Mocha sebagai yang baru, bukan override. Lihat di sini perbedaannya: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-code-override-code-and-kode-kode-baru.aspx

person CMPerez    schedule 22.01.2012
comment
Terima kasih atas penjelasannya; sekarang saya melihat perbedaannya. - person dtg; 22.01.2012

Beginilah seharusnya tampilan kode Anda.

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();
    }
}
person Elephant    schedule 16.02.2013