1、概述
空对象模式(Null Object Pattern)通过引入一个特殊的对象,该对象表现得像普通对象但却什么也不做,从而消除了对空值的检查,使代码更加简洁和健壮。
空对象模式的核心思想是用一个行为与正常对象一致的空对象来替代 null,从而避免显式的空值检查。这个空对象能够响应调用,虽然它不执行任何操作,但它确保调用不会导致程序崩溃。
角色:
AbstractObject(抽象对象):这是一个接口或抽象类,定义了具体对象和空对象共有的操作。
RealObject(真实对象):这是具体实现类,代表实际业务逻辑的对象。
NullObject(空对象):这是一个特殊的实现类,负责处理 null 情况。它实现了 AbstractObject 的所有方法,但这些方法通常不做任何事情。
Client(客户端):调用 AbstractObject 的接口,而不关心具体是 RealObject 还是 NullObject。
2、优缺点
优点:
消除空值检查:通过使用空对象,可以消除繁琐的 null 检查,使代码更加简洁和易读。
减少错误:空对象模式有效防止了空指针异常,因为空对象是一个合法的对象引用。
提高代码可维护性:代码逻辑集中在对象内部,不需要在使用对象的每个地方都进行 null 判断,代码更加一致。
遵循开闭原则:可以通过扩展新的空对象来改变行为,而无需修改现有代码。
缺点:
可能掩盖问题:使用空对象模式可能会掩盖真实的业务逻辑错误。例如,当真正需要处理 null 的情况时,空对象的使用可能会让问题难以察觉。
增加类的数量:每个需要空对象模式的地方都需要定义一个新的空对象类,这可能会增加代码库的复杂性。
不适用于所有情况:在某些情况下,明确的空值检查可能比引入空对象更清晰明了。
3、实现方式
import java.util.*;
// 4、测试
public class Test {
public static void main(String[] args) {
DogFactory dogFactory = new DogFactory();
List<Dog> dogList = new ArrayList<>();
dogList.add(dogFactory.createDog("泰迪"));
dogList.add(dogFactory.createDog("阿拉斯加"));
dogList.add(dogFactory.createDog("俊介"));
dogList.forEach(item -> {
System.out.println(item.getName());
});
}
}
// 1、定义抽象类(狗抽象类)
public abstract class Dog {
protected String name;
public abstract String getName();
public abstract void setName(String name);
}
// 2.1、定义正常狗,正常实现方法
public class RealDog extends Dog {
public RealDog(String name){
this.name =name;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
// 2.2、定义空狗,实现方法返回空字符串
public class NullDog extends Dog {
@Override
public String getName() {
return "";
}
@Override
public void setName(String name) {
}
}
// 3、实现狗工厂,根据条件返回狗的对象
public class DogFactory {
public String[] names = {"泰迪","俊介"};
public Dog createDog(String name){
for (String tempName : names){
if (tempName.equals(name)){
return new RealDog(name);
}
}
return new NullDog();
}
}
4、应用场景
对象的行为具有默认值或空行为时:例如,日志系统、事件处理系统等。当对象的某些操作可以为空操作时,空对象模式是一个很好的选择。
减少代码中的空值检查时:如果代码中充斥着大量的 null 检查,使用空对象模式可以极大地提高代码的可读性和维护性。
需要处理不确定的对象引用时:当程序中的某些对象引用可能为 null,但希望避免空指针异常时,空对象模式提供了一种优雅的解决方案。