代码之家  ›  专栏  ›  技术社区  ›  Muhammad Nasir

空对象设计模式与空对象检查

  •  10
  • Muhammad Nasir  · 技术社区  · 9 年前

    为什么空对象设计模式优于空对象检查。 如果我们查看空对象设计模式中的内存占用,我们将创建一个相同类型的新虚拟对象。这表明,如果我们在搜索查询中有大尺寸的对象和大量可为空的对象,那么这种模式将创建大量的空对象,这将比简单的检查占用更多的内存,而对于空对象,我的性能会有不可忽视的延迟。

    Null Object design pattern

    4 回复  |  直到 9 年前
        1
  •  8
  •   Community c0D3l0g1c    7 年前

    整个问题是 null 如果你试图访问 无效的 应用程序将抛出 NullPointerException 并中止。

    减少班级数量 NullXXX 在这个 空对象设计模式 (实际上只是工厂设计数据,而不是图案本身) static final NullCustomer 它总是被返回。

    在Java 8中,您可以使用 Optional 方法,以便判断函数何时不总是返回值。这种方法不会强迫您创建任意的空类,从而污染整个结构(也可能需要重构这些空类)。

    Eclipse IntelliJ 还提供编译时注释 @Nullable , @NonNull 当访问潜在的 无效的 物体。然而,许多框架没有注释。IntelliJ因此试图 discover those potential null accesses 静态分析。 除此之外,IntelliJ和Eclipse使用自己的注释( org.eclipse.jdt.annotation.NonNull , com.intellij.annotations.NotNull )这些不兼容。但是,你可以 store the annotations outside of the code 它在IntelliJ中工作。Eclipse也希望在未来实现这一点。问题是 many frameworks providing this feature 为您提供许多不同的注释。有 JSR-305 它是休眠的。它会在 javax 。我不知道为什么他们没有进一步推进。

        2
  •  1
  •   Buhake Sindi Tesnep    9 年前

    使用Null对象而不是 null 那是使用 无效的 你必须 重复 检查该对象是否确实 无效的 ,尤其是在所有需要该对象的方法中。

    在Java 8中,必须执行以下操作:

    Object o = Objects.requireNotNull(o); //Throws NullPointerException if o is indeed null.
    

    因此,如果您有一个方法不断地将同一个对象传递给不同的方法,那么每个方法在使用它之前都需要检查接收到的对象是否为空。

    因此,更好的方法是使用Null对象,或者 Optional (Java 8及更高版本),因此您不需要一直执行空检查。相反,人们会:

    Object o = optional.get(); //Throws NullPointerException if internal value is indeed null.
    //Keep using o.
    

    不需要(真的)进行空检查。事实上,你有一个 可选择的 表示您可能有值或没有值。

    空对象没有副作用,因为它通常会 没有什么 (通常所有方法都是空方法),因此不必担心性能(瓶颈/优化等)。

        3
  •  0
  •   AlexR    9 年前

    这种模式的主要区别(可能也是优势)在于清晰。考虑以下方法定义:

    public static int length(String str);
    

    此方法计算给定字符串的长度。但争论可能是 null ? 该方法将做什么?抛出异常?返回0?返回-1?我们不知道。

    通过编写好的java文档可以实现部分解决方案。下一个更好的解决方案是使用注释JSR305注释 @Nullable @NotNullable 然而,开发人员可以忽略这一点。

    但是,如果您使用的是Null对象模式(例如,番石榴或java 8的可选),则代码如下所示:

    public static int length(Optional<String> str);
    

    所以开发人员必须注意将字符串包装为Optional,从而理解参数可以为空。尝试从包含null的Optional中获取值会导致在使用正则表达式时不总是发生异常 无效的 .

    显然,使用这种模式会导致一些额外的CPU和内存消耗,这在大多数情况下并不重要。

        4
  •  0
  •   Dragan Bozanovic    9 年前

    假设你有这样的东西:

    private SomeClass someField;
    
    void someMethod() {
      // some other code
      someField.method1();
      // some other code
      someField.method2();
      // some other code
      someField.method3();
    }
    

    现在假设在以下情况下存在有效的用例: someField 可以是 null 你不想调用它的方法,但你想执行另一个 some other code 方法的部分。您需要将该方法实现为:

    void someMethod() {
      // do something
      if (someField != null) {
        someField.method1();
      }
      // do something
      if (someField != null) {
        someField.method2();
      }
      // do something
      if (someField != null) {
        someField.method3();
      }
    }
    

    通过将空对象与空(no op)方法一起使用,我们避免了样板式的空检查(以及忘记添加所有出现的检查的可能性)。

    我经常发现这在异步或可选地初始化某些内容的情况下很有用。