空对象还是虚拟对象?

mhs*_*ams 5 java oop design-patterns

考虑一个批处理操作,它可能需要也可能不需要很长时间才能完成其工作(取决于数据)。用户可以注册一个可选的侦听器来跟踪作业进度。

注意:侦听器注册完全是可选的,用户可能希望在不注册任何侦听器的情况下调用作业。

问:您更喜欢以下哪种解决方案?为什么?

编辑:这里关注的是性能干净的代码。有人说,检查空引用(解决方案 1)比第二个解决方案更快。但第二种解决方案更干净、更容易理解。我想听听您的意见。

否 1:允许空侦听器并始终检查侦听器是否不为空,然后调用它。

doMyBatchJob() {
   if (listener != null) {
      listenr.progressStarted(params);
   }
   while (x) {
      if (listener != null) {
          listener.progressUpdated(current, expected)
      }
   }
   if (listener != null) {
      listenr.progressFinished(params);
   }
}
Run Code Online (Sandbox Code Playgroud)

No 2:实现一个虚拟监听器,如果用户没有传递他/她自己的监听器,则注册它。这样就可以调用侦听器而不检查空对象。

DummyListener {
     public void progressStarted(params) { //DO NOTHING }
     public void progressUpdated(current, expected) { //DO NOTHING }
     public void progressFinished(params) { //DO NOTHING }
}

doMyBatchJob() {
   listener.progressStarted(params);
   while (x) {
         //Do a single unit of the batch operation
         // ... code omitted here
         listener.progressUpdated(current, expected)
   }
   listener.progressFinished(params)
}
Run Code Online (Sandbox Code Playgroud)

小智 4

if x==null您对代码异味的担忧是正确的,它绝对是!

使用该Null Object模式有非常充分的理由,其中之一是避免代码中充满if (x == null)噪音,这些噪音通常与业务无关,而与糟糕的设计相关。NULL表示缺少值而不是默认值。

我认为你对这种Null Object模式的运用还不够深入。

永远不要返回 null 并且你永远不需要检查它

首先,永远不要return null从方法中获取,也不要if x == null在代码中使用。两者都是糟糕设计的明确标志。null引用并且NPE应该是一个应该在没有发生的情况下解决的错误。

永远不要接受 null 并且你永远不需要检查它。

return null具有返回 a的方法Null Object并具有接受 null 的内容,并且可能处理null引用Null Object具有处理Null References.

在您的情况下,您的Dummy对象不仅不会执行任何操作,它还应该向日志警告报告它遇到了 anull并且应该对此采取措施。

使用好的 JSR305 库来注释您的方法,以便它们不接受空值。

我创建的每个Java程序中都有com.google.code.findbugsmaven依赖,无论多么琐碎,然后我可以用它来装饰每个方法和方法参数@NONNULL,而不必担心if x == null再次编写!

如果您有返回的第 3 方代码,null请将其包装起来并使用 JSR305 注释。

将 GuavaPreconditions.checkNotNull()static导入一起使用,这样您就可以checkNotNull()对所有标记的参数执行操作@Nonnnull,您甚至可以包含一条描述性错误消息,说明什么是、null为什么不应该是或其他什么。

并沾沾自喜地想想他们的代码设计得多么糟糕。

  • @pavelrappo *“有时它是一个标记或特殊值”* 这就是问题,`null` 的语义定义得很好,它是**数据的缺失**,它有一个定义良好的特殊含义,如果**你**重新定义它,你就会给其他人带来麻烦。我无法告诉你在过去 25 年里我遇到了多少代码,其中有诸如“if x == null then x = 2”之类的废话,没有任何解释,以及在其他地方没有明显原因的“x = 14” 。创建者表示这是一个错误,几十年的使用已经证明了这一点。在你的设计中避免“null”,这样其他人就不会为此付费。 (2认同)