Decorator DP の例を見ましたが、それらはすべて、具体的なオブジェクトがチェーンの最後にあることを暗示しています。
IProduct prod2 = new Sugar(new Sugar(new Sugar(new Milk(new DarkRoast()))));
Console.WriteLine("I am {0}, my cost is {1}", prod2.Name(), prod2.Cost());
DarkRoast は具体的なオブジェクトであり、その他のオブジェクトはデコレータです。したがって、私 (またはクライアント) は、誰が作成チェーンにいるのかを覚えておく必要があります。
したがって、デフォルトでは、次のことはできません。
IProduct prod2 = new Sugar(new DarkRoast(new Sugar(new Milk(new Sugar()))));
Console.WriteLine("I am {0}, my cost is {1}", prod2.Name(), prod2.Cost());
でも意味は(たぶん)同じです:ダークローストコーヒー+砂糖3+ミルク1。
そこで、次のように再設計します。
public interface IProduct {
double Cost();
string Name();
}
public class DarkRoast : IProduct {
IProduct _product;
public DarkRoast(IProduct prod = null) { _product = prod; }
public double Cost() {
if (_product != null) { return 2.5 + _product.Cost(); }
else { return 2.5; }
}
public string Name() {
if (_product != null) { return "DarkRoast " + _product.Name(); }
else { return "DarkRoast "; }
}
}
public class Milk : IProduct {
IProduct _product;
public Milk(IProduct prod = null) { _product = prod; }
public double Cost() {
if (_product != null) { return 0.5 + _product.Cost(); }
else { return 0.5; }
}
public string Name() {
if (_product != null) { return "With milk " + _product.Name(); }
else { return "With milk "; }
}
}
public class Sugar : IProduct {
IProduct _product;
public Sugar(IProduct prod = null) { _product = prod; }
public double Cost() {
if (_product != null) { return 0.2 + _product.Cost(); }
else { return 0.2; }
}
public string Name() {
if (_product != null) { return "With sugar " + _product.Name(); }
else { return "With sugar "; }
}
}
それは私ができるようにすることです
IProduct prod2 = new Sugar(new DarkRoast(new Sugar(new Milk(new Sugar()))));
Console.WriteLine("I am {0}, my cost is {1}", prod2.Name(), prod2.Cost());
だから、私は物事の順序を覚える必要はありません。そして、ここにあるものはすべてデコレータだと思います (それは悪い考えですか?) これらの実装の欠点は何ですか?