1 Null Object Pattern 空对象模式
目的:当一个对象不存在的时候,用一个空对象取代 null ,以提供默认无任何行为的对象替代品;
实现:对于对象不存在的情况返回一个预定义的空对象,而不是null。
1.我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类,还创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方;
2.一个对象需要一个协作对象,但并无具体的协作对象,而且协作对象不需要做任何事情的时候使用;
2 实现
代码场景:手机卖场去富士康订购多个品牌的手机,如果想要订购的品牌富士康在生产,则进行订购;
如果该品牌富士康不生产,富士康则会有一个官方的描述。
1. 程序中富士康生产的品牌就是具体对象角色
2. 程序中富士康不生产的品牌是空对象角色
3. 因剧情需要代码中还有两个工厂类,这个场景不同,会有不同实现
2.1 代码实现
抽象对象角色:AbstractPhone类
public abstract class AbstractPhone {
protected String phoneName;
public abstract boolean isNil();
public abstract String getPhoneName();
}
具体对象角色:ExistingPhone类
public class ExistingPhone extends AbstractPhone {
public ExistingPhone(String phoneName) {
this.phoneName = phoneName;
}
@Override
public boolean isNil() {
return false;
}
@Override
public String getPhoneName() {
return phoneName;
}
}
空对象角色:NonexistentPhone类
public class NonexistentPhone extends AbstractPhone {
@Override
public boolean isNil() {
return true;
}
@Override
public String getPhoneName() {
return "后续会增加该厂商手机产线,生产其品牌手机~";
}
}
使用了空对象的工厂类1:PhoneFactory类
public class PhoneFactory {
public static final String[] phones = {"小米", "锤子", "苹果"};
public static AbstractPhone getPhone(String name) {
for (String phoneName : phones) {
if (phoneName.equals(name)) {
return new ExistingPhone(name);
}
}
// 空对象设计模式 关键之处
return new NonexistentPhone();
}
}
未使用空对象的工厂类2:PhoneFactoryWithoutNull类
public class PhoneFactoryWithoutNull {
public static final String[] phones = {"小米", "锤子", "华为"};
public static AbstractPhone getPhone(String name) {
for (String phoneName : phones) {
if (phoneName.equals(name)) {
return new ExistingPhone(name);
}
}
// 不使用空对象思想 一般在找不到的时候 返回一个null
return null;
}
}
2.2 涉及角色
空对象模式包含如下两个角色:
(1) AbstractObject(抽象对象角色):声明协作对象的接口,如果需要,可以实现默认行为。
(2) ConcreteObject(具体对象角色):具体的协作对象类,提供有意义的行为。
(3) NullObject(空对象角色):空对象类,继承自 AbstractObject,但接口实现不做任何事情。
2.3 调用
调用者:
public class Client {
public static void main(String[] args) {
// 因为没有这个品牌手机的存在,所以订购的对象是ExistingPhone对象,而不是null
AbstractPhone apple = PhoneFactory.getPhone("苹果");
AbstractPhone xiaoMi = PhoneFactory.getPhone("小米");
AbstractPhone chuiZi = PhoneFactory.getPhone("锤子");
AbstractPhone huaWei = PhoneFactory.getPhone("华为");
System.out.println("--------------返回空对象--------------");
System.out.println("可以从富士康订购的手机:");
System.out.println(xiaoMi.getPhoneName());
System.out.println(chuiZi.getPhoneName());
System.out.println(huaWei.getPhoneName());
System.out.println(apple.getPhoneName());
System.out.println("--------------返回null---------------");
// 因为没有这个品牌手机的存在,所以订购的对象是ExistingPhone对象,而不是null
AbstractPhone nokia = PhoneFactoryWithoutNull.getPhone("诺基亚");
System.out.println("可以从富士康订购的手机:");
System.out.println(nokia.getPhoneName());
}
}
结果:
--------------返回空对象--------------
可以从富士康订购的手机:
小米
锤子
后续会增加该厂商手机产线,生产其品牌手机~
苹果
--------------返回null---------------
可以从富士康订购的手机:
Exception in thread "main" java.lang.NullPointerException
at com.wxx.behavioral.nullobject.Client.main(Client.java:21)
参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.