2

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

  1. 创建接口节点

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

  3. 使用这些类,可以在创建树时在 BST 类中删除空检查。

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

4

1 回答 1

3

是的,有一些方法可以在不显式使用 Java 的情况下实现 Null 对象模式interface。但是,您确实在做同样的事情,所以 YMMV。如果您无权访问基类和/或它不允许某种形式的扩展/覆盖,您可能会发现问题。

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

    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”类成员上使用匿名类,它会覆盖您需要覆盖的各种操作。

    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
        } 
    }
    
  • 使用抽象类来保存非空实现和空实现通用的操作,将这些方法标记为最终方法,所有其他方法都是抽象的并在两个具体类中实现——一个用于非空功能,另一个用于空功能。您可以使用静态构造函数来使常见用例易于构造并隐藏具体的类名。

    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 对象实际上只是特定值的特例(它实际上取决于类上的操作是什么)。在这种情况下,您可以拥有具有该值的静态成员或允许您创建它的静态工厂。

于 2016-02-29T00:12:54.687 回答