空对象模式
前言
空对象模式并不是Gof23种设计模式之一,但是也是一种常见的编程模式
空对象模式通常用来简化程序返回Null时的处理逻辑,让“空对象”承担处理Null的责任。
- 优点
- 大量减少if null的判断
- 缺点
- 需要扩展额外的继承,部分场景还是需要进行判断
随着Java8 Option的应用,这种模式也逐步淘汰
UML
使用接口或抽象类替换原先需要调用的类,为其添加Null对象。使用空对象执行逻辑,避免Null判断的出现
使用实例
1. 空判断
例如,我们在某段查询代码中,返回一个User类,然后调用User类的sayHi()方法。为了避免NullPointException,需要做空判断,代码可能如下
public class Test {
public static void main(String[] args) {
// 模拟10次调用
for (int i=0; i<10; i++) {
User user = getUser();
if (null != user) {
user.sayHi();
} else {
System.out.printf("第%d次getUser返回空 \n", i+1);
}
}
}
public static User getUser() {
// 模拟查询到了user或没有查询到user
long r = Math.round(Math.random() * 10);
if (r % 2 == 0) {
return new User();
}
return null;
}
}
public class User {
public void sayHi() {
System.out.println("hello world");
}
}
运行结果:
Connected to the target VM, address: ‘127.0.0.1:63237’, transport: ‘socket’
hello world
hello world
hello world
第4次getUser返回空
第5次getUser返回空
第6次getUser返回空
hello world
hello world
hello world
hello world
Disconnected from the target VM, address: ‘127.0.0.1:63237’, transport: ‘socket’
2. 空对象模式
将User需改为一个接口,添加两个实现类,DefaultUser和NullUser。前者实现具体方法,后者实现方法体为空
public interface User {
void sayHi();
}
public class DefaultUser implements User {
@Override
public void sayHi() {
System.out.println("hello, world");
}
}
public class NullUser implements User{
@Override
public void sayHi() {
// do nothing
}
}
查询时,不需要返回null,而是返回NullUser,调用者不需要再进行空判断
public class Test {
public static void main(String[] args) {
// 模拟10次调用
for (int i=0; i<10; i++) {
User user = getUser();
// 此时不需要进行空判断也不会报错
user.sayHi();
}
}
public static User getUser() {
// 模拟查询到了user或没有查询到user
long r = Math.round(Math.random() * 10);
if (r % 2 == 0) {
return new DefaultUser();
}
return new NullUser();
}
}
运行结果:
hello, world
hello, world
hello, world
hello, world
hello, world
hello, world
hello, worldProcess finished with exit code 0