Null对象设计模式与行为有关



我想分享一些我的想法和问一些问题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类?返回真或假。不清楚。

更糟糕的是,如果接口有一些属性:

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 

和user try do:

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

用户将得到奇怪的结果。用户记得,他买了8元的价格,但现在价格得0。通货膨胀?

在UnitTest中同样的问题

现在,我不想通过询问对象是否是null对象来违反OCP。

你如何解决这个问题?

如果您没有"中性"返回结果,您应该"发明"一个,并在null对象中使用它:

enum Tasty {
    Yes, No, Unknown
}
public interface IProduct {
    Tasty IsTasty();
}

写入一个空对象几乎不可避免地是一个编程错误,所以Price的实现应该像这样:

public class NullProduct : IProduct {
    //other methods...
    int Price {
        get {return 0;}
        set { throw new InvalidOperationException(); }
    }
}

可以将NullObject设计模式"完全组件化"为一个通用的可重用实现,因此您无需担心在每种情况下处理所有可能的细节(只要您需要Nullify的是接口类型)。注意,它还将处理接口函数返回另一个用户定义类型的情况。在这种情况下,它将创建另一个NullObject实例并返回它,因此您将获得一致的深层NullObject实例。

这是一个通用的可重用实现nullobject。java在这里你可以看到它是如何使用的testnullobject。java

相关内容

  • 没有找到相关文章

最新更新