实现空对象模式的方法

Ways to implement Null Object Pattern

到目前为止,我到处都看到创建空对象模式的步骤,例如在 BST 中删除空检查,如下所示:

  1. 创建接口节点

  2. 创建两个 classes 实现接口节点。其中之一是 real_Node,另一个是 null_Node.

  3. 使用那些 classes,可以在创建树时删除 BST class 中的空检查。

现在我想知道,还有其他方法可以做到这一点,例如, 我们可以只使用 classes 来实现没有接口的空对象模式吗,即在上面的步骤 (1.) 中我们可以使用 Node class 而不是 Node interface

是的,有一些方法可以在不显式使用 Java interface 的情况下实现 Null 对象模式。但是,您实际上在做很多相同的事情,所以 YMMV。如果您无法访问基础 class and/or,您可能会发现问题它不允许某种形式的 extending/overriding.

  • 创建一个 class 来扩展您的基础 class 但它通过覆盖它们来执行 'null' 操作。您通常会将其隐藏在某种静态构造函数后面以便于访问。

    class Base {
        public void someMethod() {
            // this stuff does the non-null behaviour
        }
    
        public static Base nullVersion() {
            return new NullOfBase();
        }
    
        private static class NullOfBase extends Base {
            @Override
            public void someMethod() {
               // this guy does the null version.
            }
        }
    }
    
  • 在静态'NULL'class成员上使用匿名class,它会覆盖您需要覆盖的各种操作。

    public class Base {
       public static final Base NULL = new Base() {
            @Override
            public void someMethod() {
               // this guy does the null version.
            }
        }
    
        public void someMethod() {
            // this stuff does the non-null behaviour
        } 
    }
    
  • 使用抽象class来保存非空和空实现共有的操作,将这些方法标记为final,所有其他方法都是抽象的并在两个中实现具体 classes - 一个用于非空功能,另一个用于空功能。您可以使用静态构造函数来使常见用例易于构造,并使具体的 class 名称从视图中隐藏。

    public abstract class Base {
         public final sayHello() {
             System.out.println("Hello world");
         }
    
         public abstract void someMethod();
    
         public static Base nonNullVersion() {
             return new NonNullBase();
         }
    
         public static Base nullVersion() {
             return new NullBase();
         }
    
         private static final class NonNullBase extends Base {
            @Override
            public void someMethod() {
                // this stuff does the non-null behaviour
            }
         }
    
         private static final class NullBase extends Base {
            @Override
            public void someMethod() {
                // this stuff does the null behaviour
            }
         }
    }
    

或者,有时 NULL 对象实际上只是特定值的特例(这实际上取决于 class 上的操作是什么)。在那种情况下,您可以拥有一个具有该值的静态成员或一个允许您创建它的静态工厂。