2011-11-08 15 views
1

消費者が利用できるデコレータのチェーンに状態を追加する方法を知りました。彼らはすべての印刷方法を実装し、チェーンが、それはすべて良いことだという伝播した場合デコレータパターンに状態を追加する

abstract class AbstractPizza{ 
    public abstract print(...); 
} 

class Pizza:AbstractPizza{ 
    public int Size (get; set;) 
    public print(...); 
} 

abstract class AbstractPizzaDecorator{ 
    public Pizza:AbstractPizza; 
    public abstract print(); 
} 

class HotPizzaDecorator:AbstractPizzaDecorator{ 
    public int Hotness (get; set;) 
    public print(...); 
} 

class CheesyPizzaDecorator:AbstractPizzaDecorator{ 
    public string Cheese (get; set;) 
    public print(...); 
} 


void Main() 
{ 
    BigPizza = new Pizza(); 
    BigPizza.Size = 36; 

    HotBigPizza = new HotPizzaDecorator(); 
    HotBigPizza.Pizza = BigPizza; 
    HotBigPizza.Hotness = 3; 

    HotBigCheesyPizza = new CheesyPizzaDecorator(); 
    HotBigCheesyPizza.Pizza = HotBigPizza; 
    HotBigCheesyPizza.Cheese = "Blue"; 

    HotBigCheesyPizza.print(); 
    HotBigCheesyPizza.size = 28; //ERRRRRR !!!!!!!!!!!!!!!!!!!!!!! 
} 

:この単純化したモデルを考えます。しかし、それは州のためにどのように機能するのですか? HotBigCheesyPizzaのsizeプロパティにアクセスできません。

私の欠点は何ですか?間違ったパターン?

ありがとうございます! 乾杯

+0

から書き換えられて...あなたは一例を示してもらえますか? –

答えて

1

私はあなたのコンポーネント(ピザ)とあなたの抽象デコレーター(PizzaDecorator)が同じインターフェイスを共有することになっている、その方法はデコレータの各インスタンスは、コアコンポーネント(ピザ)と同じ動作が可能であると考えています。

+0

これは、すべてのデコレータが同じプロパティを実装していることを意味します。私は状態を追加しようとしています。 HotPizzaDecoratorはサイズについて知りませんが、CheesyPizzaはホットなことを知らないようにしています。 – EasierSaidThanDone

3

デコレータパターンは、調整する必要のないクライアントの装飾されたクラスに追加の動作を追加するためのものです。したがって、装飾される物に新しいインターフェース(例えば、hotness,cheese)を追加するためのものではありません。

多分悪い例は、sizeの計算方法を変更したい場合です。サイズを英語/メトリック単位に/から変換するMetricSizePizzaDecoratorを作成できます。クライアントは、ピザが装飾されたことを知らないでしょう - ちょうどgetSize()を呼び出して、結果をどうする必要があれば(例えば、価格を計算するために)行います。

私の例ではおそらくデコレータを使用しませんが、ポイントは次のとおりです。インターフェイスを変更しないことです。実際、ほとんどすべてのデザインパターンがその点に着目しています。つまり、インターフェイスを変更せずにデザインにばらつきを加えることです。

1

状態を追加する方法の1つは、自己参照データ構造(リスト)を使用することです。しかし、これは訪問者のパターンを使用し、おそらくあなたが望む以上のことをします。このコードはどのようにあなたのHotPizzaDecoratorがCheesyPizzaDecoratorを受け入れない場合HotBigCheesyPizzaを構築しようとしているA little Java, a few patterns

// a self referential data structure with different types of nodes 
abstract class Pie 
    { 
    abstract Object accept(PieVisitor ask); 
    } 
class Bottom extends Pie 
    { 
    Object accept(PieVisitor ask) { return ask.forBottom(this); } 
    public String toString() { return "crust"; } 
    } 
class Topping extends Pie 
    { 
    Object topping; 
    Pie rest; 
    Topping(Object topping,Pie rest) { this.topping=topping; this.rest=rest; } 
    Object accept(PieVisitor ask) { return ask.forTopping(this); } 
    public String toString() { return topping+" "+rest.toString(); } 
    } 
//a class to manage the data structure 
interface PieManager 
    { 
    int addTopping(Object t); 
    int removeTopping(Object t); 
    int substituteTopping(Object n,Object o); 
    int occursTopping(Object o); 
    } 
class APieManager implements PieManager 
    { 
    Pie p=new Bottom(); 
    // note: any object that implements a rational version of equal() will work 
    public int addTopping(Object t) 
     { 
     p=new Topping(t,p); 
     return occursTopping(t); 
     } 
    public int removeTopping(Object t) 
     { 
     p=(Pie)p.accept(new RemoveVisitor(t)); 
     return occursTopping(t); 
     } 
    public int substituteTopping(Object n,Object o) 
     { 
     p=(Pie)p.accept(new SubstituteVisitor(n,o)); 
     return occursTopping(n); 
     } 
    public int occursTopping(Object o) 
     { 
     return ((Integer)p.accept(new OccursVisitor(o))).intValue(); 
     } 
    public String toString() { return p.toString(); } 
    } 
//these are the visitors 
interface PieVisitor 
    { 
    Object forBottom(Bottom that); 
    Object forTopping(Topping that); 
    } 
class OccursVisitor implements PieVisitor 
    { 
    Object a; 
    OccursVisitor(Object a) { this.a=a; } 
    public Object forBottom(Bottom that) { return new Integer(0); } 
    public Object forTopping(Topping that) 
     { 
     if(that.topping.equals(a)) 
      return new Integer(((Integer)(that.rest.accept(this))).intValue()+1); 
      else return that.rest.accept(this); 
     } 
    } 
class SubstituteVisitor implements PieVisitor 
    { 
    Object n,o; 
    SubstituteVisitor(Object n,Object o) { this.n=n; this.o=o; } 
    public Object forBottom(Bottom that) { return that; } 
    public Object forTopping(Topping that) 
     { 
     if(o.equals(that.topping)) 
      that.topping=n; 
     that.rest.accept(this); 
     return that; 
     } 
    } 
class RemoveVisitor implements PieVisitor 
    { 
    Object o; 
    RemoveVisitor(Object o) { this.o=o; } 
    public Object forBottom(Bottom that) { return new Bottom(); } 
    public Object forTopping(Topping that) 
     { 
     if(o.equals(that.topping)) 
      return that.rest.accept(this); 
      else return new Topping(that.topping,(Pie)that.rest.accept(this)); 
     } 
    } 
public class TestVisitor 
    { 
    public static void main(String[] args) 
     { 
     // make a PieManager 
     PieManager pieManager=new APieManager(); 
     // add some toppings 
     pieManager.addTopping(new Float(1.2)); 
     pieManager.addTopping(new String("cheese")); 
     pieManager.addTopping(new String("onions")); 
     pieManager.addTopping(new String("cheese")); 
     pieManager.addTopping(new String("onions")); 
     pieManager.addTopping(new String("peperoni")); 
     System.out.println("pieManager="+pieManager); 
     // substitute anchovies for onions 
     int n=pieManager.substituteTopping(new String("anchovies"),new String("onions")); 
     System.out.println(n+" pieManager="+pieManager); 
     // remove the 1.2's 
     n=pieManager.removeTopping(new Float(1.2)); 
     System.out.println(n+" pieManager="+pieManager); 
     // how many anchovies do we have? 
     System.out.println(pieManager.occursTopping(new String("anchovies"))+" anchovies"); 
     } 
    } 
関連する問題