2017-10-30 5 views
0

私はデコレータパターンについてthis articleを読んだことがあります。Java:デコレータパターン - 主な抽象クラスへの参照

抽象クラスSandWichDecoratorからこのクラスinhertis:

public class CheeseDecorator extends SandWichDecorator{ 
    Sandwich currentSandwich; 

    public CheeseDecorator(Sandwich sw){ 
     currentSandwich = sw; 
    } 

    @Override 
    public String getDescription(){ 
     return currentSandwich.getDescription() + ", Cheese"; 
    } 
    @Override 
    public BigDecimal price() { 
     return currentSandwich.price().add(new BigDecimal("0.50")); 
    } 
} 

なぜabstractクラスCheeseDecoratorクラスのSandwichSandwich currentSandwich;への参照?

抽象クラスSandWichDecoratorに入れるのは簡単でしょうか? そして、すべてのクラスがSandWichDecoratorに拡張されると自動的に参照があります。

+1

「サンドイッチ」は1語です。それは大文字のWを必要としません。 – khelwood

+0

抽象クラス内でSandwich属性を宣言すると、すべてのサブクラスでこのパラメータを使用してコンストラクタを実装する必要があります。 –

+0

そのWebサイトで与えられた例では、クラスSandWichDecoratorは有用なものを追加しません。私はなぜ作者がそれに悩まされているのか分かりません。チーズデコレーターでサンドイッチを直接拡張することもできます。 – DodgyCodeException

答えて

2

はい、あなたは正しいです。

public abstract class SandwichDecorator implements Sandwitch { 

    protected final Sandwitch current; 

    public SandwichDecorator(Sandwitch current) { 
     this.current = current; 
    } 

} 

しかし、実際に、あなたも SandwichDecoratorクラスは必要ありません:あなたはこのように、 SandwichDecoratorcurrentサンドイッチを持つことができます。あなたはインターフェイス Sandwichを持ってそれを実装することができます。インターフェースとデザイン

Sandwich completeSandwich = new CheeseSandwich(new BasicSandwich()); 

は抽象クラスと比べてより柔軟である:あなたはこのようにそれを使用することができます

interface Sandwich { 
    String description(); 
    float price(); 
} 

class BasicSandwich implements Sandwich { 
    @Override 
    public String description() { 
     return "Sandwich"; 
    }  
    @Override 
    public float price() { 
     return 4f; 
    }  
} 

class CheeseSandwich implements Sandwich { 
    private final Sandwich origin; 
    public CheeseSandwich(Sandwich origin) { 
     this.origin = origin; 
    } 
    @Override 
    public String description() { 
     return origin.description() + " , Cheese"; 
    }  
    @Override 
    public float price() { 
     return origin.price() + 1f; 
    } 
} 

//More implementations of Sandwich 

:それはちょうど「飾ら」の参照を保持するための抽象クラスを持っている価値はありません。あなたが書くたびに、少し猫が死ぬextends

+1

あなたの説明のためにヘクトルに感謝します。私は マスタードとマヨネーズのビットで自分の例を試してみましたが、インターフェイスを使って作業しました(私は 小さな猫のどちらかを殺したくありません:-))。 – Peter

2

あなたの提案は上手くIMHOです。 また、GOFのオリジナルと一致します。 decorator

一般のパターンを議論する、それが変異体はない「パターン・ポリス」(限り、それはよく考えられていたように)すべての小さな偏差のためにあなたを叱責するがありません、許容可能であることを覚えておくことが重要です...それが私だったら、記事のAbstractClassesのいくつかをインターフェースに変更したいと思っていましたが、私はまだ私の設計意図がはっきりと受け入れられると信じています。

おそらく、あなたはコメントの著者に尋ねることができます(これは古い投稿ですが)。私が推測しなければならなかったのは、 "currentSandwich"宣言/場所(threadLocalから取り出し、2つのサンドイッチをまとめるなど)に柔軟性を残そうと思っていたと思いますが、そのような「創造性」は一般性モジュラー性 - つまり、複数のデコレータを1つにまとめて自由にラップすることができます。私は自分のデコレータが明確に定義された "currentSandwitch"に固執することを望んでいます。その場合、あなたのアイデアを採用するのはうまくいきます。

+0

ありがとうPelit Mamani、私は抽象クラスよりもむしろインタフェースを使って、Hectorが示すアプローチに似ています。 – Peter

2

パターンの本質は、新しい機能/変更された挙動は、同じクラスのオブジェクトの挙動に影響を与えることなく、静的または動的オブジェクトに追加することを可能にします。

これを達成するには、多型性を活用します。基本抽象クラスまたはインタフェースは、装飾のために入力および出力として渡されるオブジェクトの「カテゴリ」を提供します。

これはパターンを披露するために、著者が選択しただけの方法であり、私はそれが希薄なことができることをあなたに同意。

Hector(SandwichDecoratorクラスなし)が提供する例は私の意見では、この例のパターンのより良い実装です。

+0

説明もありがとうございます。 – Peter

関連する問題