1

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());

だから、私は物事の順序を覚える必要はありません。そして、ここにあるものはすべてデコレータだと思います (それは悪い考えですか?) これらの実装の欠点は何ですか?

4

1 に答える 1

1

これは私には合理的に見えますが、デフォルトのデリゲート オブジェクトとして使用される具体的なNull オブジェクトを追加して、null チェックを回避することで、わずかに改善される可能性があります。

あなたの言語構文に関する私の知識をモジュール化すると(実際には使用しない言語です)、これは次のようになります。

public class Empty : IProduct
{

    public double Cost()
    {
        return 0.0;
    }

    public string Name()
    {
        return "";
    }
}


public class Sugar : IProduct
{
    IProduct _product;


    public Sugar(IProduct prod = null) 
    {  
        _product = (prod == null) ? new Empty() : prod;
    }

    public double Cost()
    {
        return 0.2 + _product.Cost();
    }

    public string Name()
    {
        return "With sugar " + _product.Name();
    }
}
于 2012-09-02T14:00:06.777 に答える