2017-02-13 17 views
5

私はデコレータデザインパターンの一例を読みました。私は、このデザインパターンがある特定のインスタンスの動作を動的に変更することを理解しました。私が下に示した例もまた理解できる。私が理解していなかった点は、乳製品にc.getCost()と呼ぶと、1.5を返します。 唯一SimplecoffeegetCost()は1を返しますが、どこからc.getCostのミルクリターン1.5ですか?Decoratorパターンチェーンメソッドはどのように呼び出されますか?

MilkクラスとSimplecoffeeクラスの間のリンクを説明してください。ミルクオブジェクトで呼び出されたときにメソッドgetCost()の実行がどのように流れますか? getCost()メソッドは1.5をどのように返しますか? getCost()メソッドは1.5を返しますどのように

//Decorator Design Pattern 
interface Coffee { 
    public double getCost(); 

    public String getIngredients(); 
} 

class Simplecoffee implements Coffee { 
    public double getCost() { 
     return 1; 
    } 

    public String getIngredients() { 
     return "Coffee"; 
    } 
} 

abstract class CoffeeDecorator implements Coffee { 
    protected Coffee decoratedcoffee; 
    protected String ingredientseparator = ":"; 

    public CoffeeDecorator(Coffee decoratedcoffee) { 

     this.decoratedcoffee = decoratedcoffee; 
    } 

    public double getCost() { 
     return decoratedcoffee.getCost(); 
    } 

    public String getIngredients() { 
     return decoratedcoffee.getIngredients(); 
    } 
} 

class Milk extends CoffeeDecorator { 

    public Milk(Coffee decoratedcoffee) { 

     super(decoratedcoffee); 
     System.out.println("Milk Constructor"); 
    } 

    public double getCost() { 
     return super.getCost() + 0.5; 
    } 

    public String getIngredients() { 
     return super.getIngredients() + ingredientseparator + "milk"; 
    } 
} 

public class Decorator {  
    public static void main(String[] ar) { 
     System.out.println("calling simplecoffee in main"); 
     Coffee c = new Simplecoffee(); 
     System.out.println("Cost:" + c.getCost()); 
     c = new Milk(c); 
     System.out.println("Cost:" + c.getCost()); 
    }  
} 
+0

あなたは見つけるためにSimplecoffee' 'の' getCost'方法で 'Thread.dumpStackを()'を挿入できます。 –

+0

基本的には、c = new Milk(c)と言ったときに、SimpleCoffeeインスタンスをフィールド(Interface Coffee経由で参照される)として設定し、decorcoffee.getCost();を呼び出して継承を呼び出しているCoffeeDecoratorコンストラクタです。継承を継承して1を返し、0.5を追加する親メソッドです。 – drgPP

+0

「ミルクオブジェクトで呼び出されたときにメソッドがどのように流れるか」LOL – Reg

答えて

5

Milk

最初のコールSimpleCoffeeへの参照であるdecoratedcoffeegetCost方法でgetCost()方法。したがって、getCostメソッドはSimpleCoffeeから1を返します(read:runtime polymorphism)。次に、MilkgetCost方法は、この呼び出しの戻り値を追加します(すなわち1)0.5することが1.5

としてあなたに結果を与えるこれはデコレータパターンの全体のポイントです。 デコレータは、新しいオブジェクトを既存のチェーンにラップすることによってメソッド呼び出しの連鎖を作成するために使用されます。

1

MilkクラスをMilkedCoffeeという名前にしたいと思います。デコレータは元のオブジェクトをラッピングして、元のオブジェクトの同じインタフェースに属しているので、クライアントコードがコーヒー(元のクラス)かミルクコーヒー(デコレータ)か、アイスコーヒー(別のデコレータ)。あなたの例で装飾されたコーヒーはコーヒーでなければなりません。牛乳、砂糖などのコーヒーに加えることはできません。その他

元の質問に答えるには、 (MilkedCoffeeとして飾られ、他の言葉で)コーヒーはミルクで提供していますコスト

1

は、私たちは、コードのこの部分を見て、理解してみましょう:

coffee c = new simplecoffee(); 
System.out.println("Cost:" + c.getCost()); 
  • simplecoffeeオブジェクトを作成し、cに割り当て。 (simplecoffeeコーヒーインターフェースの実装であるため、問題はない)
  • c
  • コーヒーを入力するように宣言されます。

次のステップ:

c = new milk(c); 
System.out.println("Cost:" + c.getCost()); 
  • cの古い値を上書き)ミルクオブジェクトを作成し、新しいミルクオブジェクトにcを割り当てます。
  • ミルクは、コーヒーインターフェイスも実装する抽象クラスcoffeedecoratorを拡張しています。
  • simplecoffeeオブジェクトは、クラスのインスタンス変数に割り当てられます。

    public double getCost(){ 
    
         return super.getCost() + 0.5; 
        } 
    
    • super.getCost()coffeedecoratorクラスで実装されています

    は、最後の印刷が前に呼び出されmilk.getCost()の実装を考えてみましょう。単にメソッドcoffeeインスタンスを内部で呼び出します。

  • simplecoffee 1の費用がかかります。
  • 牛乳は0.5です。

だから一緒になって1.5。

Greets Alan。

0

MilkクラスとSimplecoffeeクラスの間のリンクと、ミルクオブジェクトで呼び出されたときにgetCost()メソッドの実行がどのように流れるかを説明できます。 getCost()メソッドは1.5をどのように返しますか?

visualization of the Decorator calls in Head First Design Patternsよりうまくいくのは難しいです。下の緑色の矢印に従ってください。 getCost()への呼び出しはネストされ、戻り値も緑色で表示されます。画像はまたMilkSimplecoffeeクラスをラップする方法も示しています。

enter image description here

関連する問題