【问题标题】:NullObject Pattern: How to handle fields?NullObject 模式:如何处理字段?
【发布时间】:2016-09-13 01:49:20
【问题描述】:

假设我们有 Book 类,其中包含 year_published 公共字段。如果我想实现 NullObject 设计模式,我需要定义 NullBook 类,它的行为与 Book 相同,但不做任何事情。

问题是,NullBook 在分配字段时应该是什么行为?

Book book = find_book(id_value);  //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016;  //What should we do here?!

【问题讨论】:

  • 您应该首先不要直接访问属性(将它们定义为私有)并使用 setter。所以你可以控制你在课堂上分配的价值。
  • 但通常这并不总是可能的。
  • 另外,您可以假设代码位于类方法之一中。所以它也可以访问私有字段。

标签: oop nullpointerexception null null-object-pattern


【解决方案1】:

您应该做的第一件事就是将您的属性设为私有。

class NullBook {
    private year_published;
    // OR solution2 private year_published = null;

    public setYearPublished(year_published) {
        this.year_published = null;
        // OR solution2 do nothing!
    }
}

您也可以在父类中定义私有字段,因此子类必须实现 setter 才能访问该字段

class Book {
  private year_published;

  public setYearPublished(year_published) {
     this.year_published = year_published;
  }
}

class NullBook extends Book {
    public setYearPublished(year_published) {
        parent::setYearPublished(null);
    }
}

为什么要使用 getter 和 setter? https://stackoverflow.com/a/1568230/2377164

【讨论】:

  • 如果代码位于也可以访问私有字段的类方法之一中怎么办?
  • 假设问题中的示例代码位于类方法中(因此它也可以访问私有字段)。这意味着,即使字段被标记为私有,问题仍然存在。
  • 在 NullBook 的类方法中?那么您是该类的开发人员,正确实施它以避免来自您的类“外部”的人将您的字段设置为另一个值而不是 null。每次需要编写字段时都使用 setter。我没有看到问题,也许我误解了你的意思。
  • 所以我们可以利用 NullObj 模式的唯一方法是没有公共字段。对吗?
  • 唯一的方法是控制字段的设置方式,所以它有一个可以控制的setter,所以到目前为止我能看到的唯一方法是把属性私有化。
【解决方案2】:

问题是:模式是关于平衡。是的,一般来说,不返回 null 而是让 else 返回是一种很好的做法;但好吧:返回的内容应该仍然有意义!

在某种程度上,我看不出拥有“NullBook”对您的应用程序设计有何帮助。特别是当您允许访问各种内部字段时。您准确地问了正确的问题:这样的“NullBook”的出版年份、作者或……应该是什么?! 例如,当某些代码对来自不同“来源”的书籍进行“查找”时会发生什么;然后尝试按出版年份对这些书籍进行排序。您肯定不希望您的 NullBook 成为此类数据的一部分。

因此我看不到拥有这个类的价值,相反:我认为它可能会产生“有趣”的错误;因此我的回答是:退后一步,重新考虑你是否真的需要这门课。

除了空替换对象还有其他选择:也许您的语言允许 Optionals;或者,您重新设计那些可能返回 null ... 以返回书籍集合/数组的方法;并且有疑问:该列表/数组只是空的。

长话短说:允许其他类直接访问私有字段更像是一种进口设计气味;所以你不应该太专注于 NullObjects,而另一方面却很容易放弃像 Information Hiding 这样重要的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多