7

このスレッドDecorator pattern implementationには、抽象クラスを使用したデコレータの実装があります。CondimentDecorator は、そこにある実装では Beverage ではないという単純な事実のために、私はそれが好きではありません。代わりにインターフェースを使用します。抽象クラスは is-a 関係に適していて、インターフェースは has-a 関係に適しているのではないでしょうか?

public interface IBeverage
{
    // get a description of the beverage
    String Description { get; }

    // calculate cost of the beverage
    double Cost { get; }
}

// HouseBlend coffee implements IBeverage
public class HouseBlend : IBeverage
{
    private string description;
    public String Description
    {
        get { return description; }
    }

    private double cost;
    public double Cost
    {
        get { return cost; }
    }

    // Constructor
    public HouseBlend() { description = "House Blend"; cost = 0.89;  }
}

// DarkRoast coffee implements IBeverage
public class DarkRoast : IBeverage
{
    private string description;
    public String Description
    {
        get { return description; }
    }

    private double cost;
    public double Cost
    {
        get { return cost;  }
    }

    // Constructor
    public DarkRoast() { description = "Dark Roast"; cost = 1.10; }
}

// Mocha is a Decorator
public class Mocha
{
    // Mocha has-a Beverage
    private IBeverage m_beverage;

    private string description;
    public String Description
    {
        get { return description; }
    }

    private public double Cost
    {
        get { return cost; }
    }

    // Constructor binds the object passed to member var
    public Mocha(IBeverage beverage)
    {
        m_beverage = beverage; // not necessary for the purpose of this example
        description = m_beverage.Description + ", Mocha";
        cost = 0.20 + m_beverage.Cost;
    }
}

Use like this:
    Mocha mhb = new Mocha(new HouseBlend()); // house blend with mocha flavor
4

1 に答える 1

4

is-a 関係をモデル化するために、基本クラスとインターフェイスの両方が頻繁に使用されます。IDisposable「手動でライフサイクルを制御するオブジェクト」、「使い捨て」と理解できるほど単純なインターフェースでさえ。より具体的な違いは、基本実装またはデータ フィールドが許可されるかどうかにあります。そして、複数の階層を組み合わせる能力にあります。

さて、パターンを実装するときは、通常、データ フィールドが必要かどうかを確認するのに十分な情報があります。ただし、ソフトウェアが成長するにつれて、同じクラスを追加のパターンに含める必要が将来生じる可能性を排除することはほとんどできません。その観点からすると、抽象クラスよりも一般的にインターフェースを優先することで、選択肢があればいつでも、より長期的な柔軟性が得られます。

デコレーターの性質上、選択肢があります。通常、コンポーネントには、ネストする順序が事前に定義されていません。もしそうなら、コンポーネントの代わりに継承を直接使用します。そのため、Decorator を構成するインターフェイスを優先する必要があります。

そうは言っても、あなたの元の議論も有効です。デコレータ コンポーネント (機能) は、必要に応じて is-a 関係として理解できます。しかし、それはそれらを見る最も自然な方法ではありません。

于 2013-04-18T20:50:21.827 に答える