null_object

第二十六章 空对象模式(Null Object Pattern)

1 概要

空对象模式(Null Object Pattern)是一种行为模式(Behavior Design Patters)。在面向对象程序设计中,一种常见的错误是空指针异常(Null Pointer Exception)。在解释运行类型的语言中(例如:Java或者Python语言),开发人员需要捕捉空指针异常,以使得在异常出现时,程序能够继续正常运行。在编译运行类型的语言中(例如:C++语言),程序会自动错误退出。为了解决这个问题,开发人员提出了多种解决方案,其中,空对象模式就是其中一种解决方案。空对象模式的设计思想是当空指针异常发生时,程序不做任何处理,继续运行。

空对象模式是否是最合适的解决方案是另外一个问题。本文主要介绍空对象模式的原理和使用方法。

2 空对象模式的结构

在空对象模式中,有三个参与方。

  1. Subject接口定义了某一功能接口。
  2. ConcreteSubject类实现了Subject接口,并完成了真实的业务逻辑处理。
  3. NullSubject类实现了Subject接口,但是并没有实现任何实质的逻辑。

图一 空对象模式结构

图一 空对象模式结构。

3 空对象模式示例

我们将使用一个简单的例子来解释空对象模式的使用方法。假设系统中定义了一个接口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();
	}
}

4 小结

本章介绍了空对象模式的结构和使用方法。使用空对象能够避免空指针异常的错误。虽然,空对象模式可能并不是最好的解决方案,但是,空对象模式常用于许多大型项目之中,能有效的提高代码的整体质量。

上一章
下一章

注册用户登陆后可留言

Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.