1

私は自分の考えをいくつか共有し、いくつかの質問をしたいと思います ニュートラルな動作でクラスを実装することになっている Null オブジェクトの設計パターン。したがって、インターフェイスを実装する必要がある場合:

public interface IProduct 
{
    double Cost();
    string Name();
}

おそらく、次の実装を使用します。

public class NullProduct : IProduct
{
    public double Cost()
    {
        return 0.0;
    }

    public string Name()
    {
        return String.Empty;
    }
}

罰金。

しかし、次のインターフェイスを実装する必要がある場合、どの戦略を使用する必要がありますか:

public interface IProduct 
{
    //other methods...
    bool IsTasty();
}

IsTasty - 「ニュートラル」な動作はありません。NullProduct クラスにどのように実装すればよいですか? true または false を返します。いいえ、それほど明確ではありません。

さらに悪いことに、インターフェースにいくつかのプロパティがある場合:

public interface IProduct 
{
    //other methods...
    int Price{get;set;}
}

と実装:

public class NullProduct : IProduct 
{
    //other methods...
    int Price
    {
        get {return 0;}
        set {/*nothing*/}
    }
}

なんで?そのため、次のように、一部のユーザーがオブジェクトを取得する場合:

    IProduct prod = GetSomeObject(); //GetSomeObject returns NullProduct 

そしてユーザーは次のことを試みます:

    prod.Price = 8;
    Console.WriteLine(prod.Price);

ユーザーは奇妙な結果を得るでしょう。ユーザーは覚えています。彼は 8 ドルの価格を設定しましたが、現在は価格が 0 になっています。インフレですか。

UnitTest で同じ問題。

今、オブジェクトがnullオブジェクトかどうかを尋ねることでOCPに違反したくありません。

問題をどのように解決しますか?

4

2 に答える 2

2

「ニュートラル」な戻り値がない場合は、それを「発明」し、null オブジェクトで使用する必要があります。

enum Tasty {
    Yes, No, Unknown
}

public interface IProduct {
    Tasty IsTasty();
}

null オブジェクトへの書き込みはほぼ必然的にプログラミング エラーになるため、 の実装は次のPriceようになります。

public class NullProduct : IProduct {
    //other methods...
    int Price {
        get {return 0;}
        set { throw new InvalidOperationException(); }
    }
}
于 2012-12-26T06:53:52.110 に答える
0

NullObject デザイン パターンを汎用の再利用可能な実装に "完全にコンポーネント化" することができるため、それぞれのケースで可能なすべての詳細を処理することを心配する必要はありません (Nullify する必要があるものがインターフェイス型である限り)。インターフェイス関数が別のユーザー定義型を返す場合も処理されることに注意してください。この場合、別の NullObject インスタンスを作成して返すため、深い NullObject インスタンスを一貫して取得できます。

これは再利用可能な汎用実装NullObject.javaであり、 TestNullObject.javaの使用方法を確認できます。

于 2012-12-26T17:04:20.200 に答える