38.5 空对象模式

38.5 空对象模式

空对象模式(Null Object Pattern)是通过实现一个默认的无意义对象来避免null值出现, 简单地说,就是为了避免在程序中出现null值判断而诞生的一种常用设计方法。

38.5.1 空对象模式的例子

举个简单的例子来说明,我们写一个听动物叫声的模拟程序,如代码清单38-38所示。

代码清单38-38 动物叫声

1
2
3
4
5
6
7
8
9
10
//定义动物接口
public interface Animal {
public void makeSound();
}
//定义一个小狗
class Dog implements Animal{
public void makeSound(){
System.out.println(“Wang Wang Wang!”);
}
}

然后再定义一个人来听动物的叫声,如代码清单38-39所示。

代码清单38-39 听动物叫声的人

1
2
3
4
5
6
7
8
public class Person {
//听到动物叫声
public void hear(Animal animal){
if(animal !=null){
animal.makeSound();
}
}
}

注意看粗体部分,也许你觉得程序没有什么问题,输入参数animal是应该做空值判断。 但是,我们这样思考:在一个完整的系统中,animal对象是如何产生?什么原因会产生null 值?如果我们能够控制住null值的产生,是不是就可以去掉这个空值判断了?那这样,程序是不是更易读更简单?好,我们就编写一个更完美的程序,增加一个NullAnimal类,如代码清单38-40所示。

代码清单38-40 增加一个NullAnimal

1
2
3
4
class NullAnimal implements Animal{
public void makeSound(){
}
}

增加了NullAnimal类后,在Person类中就不需要”animal!=null”这句话了,因为我们提供了一个实现接口的所有方法,不会再产生null对象。想象一个Web项目中,animal对象可能由MVC框架映射产生,我们只要定义一个默认的映射对象是NullAnimal,就可以解决空值判断的问题,提升代码的可读性。这就是空对象模式(一些项目组把它作为编码规范的一部分),非常简单,但非常实用。

38.5.2 最佳实践

空对象模式是通过空代码实现一个接口或抽象类的所有方法,以满足开发需求,简化程序。它如此简单,以至于我们经常在代码中看到和使用,对它已经熟视无睹了,而它无论是事前规划或事后重构,都不会对我们的代码产生太大冲击,这也是我们“藐视”它的根本原因。