代码之家  ›  专栏  ›  技术社区  ›  Johannes Rudolph

Fowler空对象模式:为什么使用继承?

  •  4
  • Johannes Rudolph  · 技术社区  · 14 年前

    为什么Fowler Poeaa第498页用以下方式定义了空对象模式(示例缩短,语言是C但并不重要):

    public class Customer
    {
      public virtual string Name {get; set;}
    }
    
    public class NullCustomer : Customer, INull
    {
      public override Name 
      {
         get { return "ImTheNull";}
         // setter ommitted
      }
    }
    

    INull 用作标记接口。 我不喜欢这种方法有三个原因:

    1. 属性需要标记为虚拟
    2. 我不能再密封我的实体类了
    3. 至少引入(n+1)个新类型(n个空对象,一个标记接口)

    为什么不这样实施:

    public class Customer
    {
      public static readonly Customer NullCustomer = new Customer(){Name = "ImtTheNullCustomer";}
    
      public string Name {get; set;}
    }
    

    我发现所有的家禽例子都是经过深思熟虑的,很明显我在这里遗漏了一些东西。

    4 回复  |  直到 8 年前
        1
  •  10
  •   Greg Mattes    14 年前

    继承的原因是重写类的行为。在我看来,你想的方式是检查你所拥有的物体是否等于 NullCustomer 静态实例来作出决定,但是空对象的点是维护 Liskov's substitution principle .

    换句话说,您使用空对象来设置引用,并且不会对其进行特殊检查,您只会使用它,并且它应该具有不同的行为(实际上是缺乏行为)。

        2
  •  1
  •   Alister Bulman    14 年前

    使用magic值的第二个示例的问题是,如果您的类有属于该类的其他项,那么现在必须插入对magic的检查,以决定返回信息或其他适当的信息。

    对于空类,该类返回最有意义的内容,而不需要进行此类检查。

    例如,在适当地询问数据库之后,customer类可能返回该用户花费的总美元。一个空客户只需要 return 0; . 使用magic值,它要么从数据库中获取虚拟用户的信息,要么在执行明智的操作之前运行另一个特定的检查。

        3
  •  0
  •   monksy    14 年前

    加之查普的话。使用空对象模式,以便有一组可接受的默认值。此外,如果您试图在MVC中使用NullCustomer,您仍然可以访问表示模型的对象,而不必考虑潜在的非现有数据。[正在检查空值]

        4
  •  0
  •   Tom Hawtin - tackline    14 年前

    我不是C程序员,但在第二个示例中,您可以等效于:

    Customer.NullCustomer.Name = "Not Null";
    

    一般来说,对象具有行为,而不仅仅是数据,因此它变得更加复杂。

    推荐文章