空对象模式(Null Object Pattern)是一种行为模式(Behavior Design Patters)。在面向对象程序设计中,一种常见的错误是空指针异常(Null Pointer Exception)。在解释运行类型的语言中(例如:Java或者Python语言),开发人员需要捕捉空指针异常,以使得在异常出现时,程序能够继续正常运行。在编译运行类型的语言中(例如:C++语言),程序会自动错误退出。为了解决这个问题,开发人员提出了多种解决方案,其中,空对象模式就是其中一种解决方案。空对象模式的设计思想是当空指针异常发生时,程序不做任何处理,继续运行。
空对象模式是否是最合适的解决方案是另外一个问题。本文主要介绍空对象模式的原理和使用方法。
在空对象模式中,有三个参与方。
图一 空对象模式结构。
我们将使用一个简单的例子来解释空对象模式的使用方法。假设系统中定义了一个接口Subject。它有一个成员方法print(),用于打印一些信息。
public Interface Subject {
public void print();
}
ConcreteSubject类实现了Subject接口。在print()成员方法中打印一条字符串"This is ConcreteSubject."。
public class ConcreteSubject implements Subject {
@Override
public void print() {
System.out.println("This is ConcreteSubject.");
}
}
为了避免出现空指针异常(NullPointerException),我们创建了NullSubject类,实现了Subject接口。在print()成员方法中,没有实现任何内容。
public class NullSubject implements Subject {
@Override
public void print() {
// 发生了空指针异常,什么也不用做。
}
}
在使用时,每当声明一个Subject对象变量时,将其初始化为一个NullSubject对象。所以,在整个程序中不会存在指向null的对象,从而避免空指针异常的出现。
public class NullObjectExample {
public static void main(String[] args) {
Subject s1 = null;
s2.print(); // 会发生空指针异常(Null Pointer Exception)
Subject s2 = new NullSubject();
s2.print(); // 不会发生空指针异常
}
}
在一个大型项目中,项目可能有着成百上千的接口。使用空对象模式需要为这些接口都实现一个空类。完成这些空类也为开发人员带来了额外的负担。小水滴建议读者可尝试使用动态代理模式,动态的为每个接口生成一个空的实现类。
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
public class DynamicProxyExample {
public static void main(String[] args) {
// 生成一个实现Subject接口的空对象
Subject s = (Subject)Proxy.newProxyInstance(
Subject.class.getClassLoader(),
new Class<?>[] {Subject.class},
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
s.print();
}
}
本章介绍了空对象模式的结构和使用方法。使用空对象能够避免空指针异常的错误。虽然,空对象模式可能并不是最好的解决方案,但是,空对象模式常用于许多大型项目之中,能有效的提高代码的整体质量。
注册用户登陆后可留言