到目前为止,我已经看到了创建Null对象模式的步骤,例如在BST中删除空检查的步骤如下:
创建接口Node
创建两个实现接口Node的类。其中一个是real_Node,另一个是null_Node。
使用这些类时,可以在创建树时在BST类中删除空检查。
现在我想知道,还有其他方法可以做到这一点,例如, 我们可以在没有使用类的接口的情况下实现Null对象模式,即在上面的步骤(1)中我们可以使用Node类而不是Node接口
答案 0 :(得分:3)
是的,有一些方法可以在不显式使用Java interface
的情况下实现Null对象模式。然而,你真的做了很多同样的事情,所以YMMV。如果您无法访问基类和/或它不允许某种形式的扩展/覆盖,您可能会发现问题。
创建一个扩展基类的类,但是它会执行' 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'上使用匿名类。类成员,它会覆盖您需要覆盖的各种操作。
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
}
}
使用抽象类来保存非null和null实现共有的操作,将这些方法标记为final,所有其他方法都是抽象的,并在两个具体的类中实现 - 一个用于非null功能和另一个null功能。您可以使用静态构造函数来保持易于构造的常见用例和隐藏在视图中的具体类名。
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对象实际上只是特定值的特殊情况(它实际上取决于类上的操作)。在这种情况下,您可以拥有具有该值的静态成员,也可以使用允许您创建它的静态工厂。