原文:http://www.runoob.com/design-pattern/
少许个人理解,如有错误请指出。欢迎一起讨论。

在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。
在空对象模式中,我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类,还创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方。

目的:(原文没有提及,以下整理自http://www.2cto.com/kf/201504/388387.html)
比如我们在写Java Web项目时有个方法叫getBookInfoByIndex,目的是返回Book对象之后再调用book.show方法来获取某个书籍的基本信息。如果我们输入1,2,3等等可以查询到的数字,程序运行正常,但是一旦我们输入-1,或者超过书本数量的index,那不就会报错么。此时我们比较常规的做法就是在客户端加一个判断,判断是否为null。如果为null的话,就不再调用show()方法。但是,你有没有考虑过?这样做,确实消除了报错,但是这样做真的好吗?你想如果在一段程序中有很多处调用getBookInfoByIndex()方法,岂不是很多处都要判断book对象是否为null?这还不算坏,如果哪一处没有判断,然后报错了,很有可能导致程序没法继续运行甚至崩溃。

代码实现
我们将创建一个定义操作(在这里,是客户的名称)的 AbstractCustomer 抽象类,和扩展了 AbstractCustomer 类的实体类。工厂类 CustomerFactory 基于客户传递的名字来返回 RealCustomer 或 NullCustomer 对象。
NullPatternDemo,我们的演示类使用 CustomerFactory 来演示空对象模式的用法。

空对象模式的 UML 图

步骤 1
创建一个抽象类。
AbstractCustomer.java

public abstract class AbstractCustomer {protected String name;public abstract boolean isNil();public abstract String getName();
}

步骤 2
创建扩展了上述类的实体类。
RealCustomer.java

public class RealCustomer extends AbstractCustomer {public RealCustomer(String name) {this.name = name;     }@Overridepublic String getName() {return name;}@Overridepublic boolean isNil() {return false;}
}

NullCustomer.java

public class NullCustomer extends AbstractCustomer {@Overridepublic String getName() {return "Not Available in Customer Database";}@Overridepublic boolean isNil() {return true;}
}

步骤 3
创建 CustomerFactory 类。
CustomerFactory.java

public class CustomerFactory {public static final String[] names = {"Rob", "Joe", "Julie"};public static AbstractCustomer getCustomer(String name){for (int i = 0; i < names.length; i++) {if (names[i].equalsIgnoreCase(name)){return new RealCustomer(name);}}return new NullCustomer();}
}

步骤 4
使用 CustomerFactory,基于客户传递的名字,来获取 RealCustomer 或 NullCustomer 对象。
NullPatternDemo.java

public class NullPatternDemo {public static void main(String[] args) {AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");System.out.println("Customers");System.out.println(customer1.getName());System.out.println(customer2.getName());System.out.println(customer3.getName());System.out.println(customer4.getName());}
}

步骤 5
验证输出。

Customers
Rob
Not Available in Customer Database
Julie
Not Available in Customer Database

这个设计模式应该是相当好理解的。

设计模式笔记二十二:空对象模式相关推荐

  1. Java进阶篇设计模式之十三 ---- 观察者模式和空对象模式

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  2. Java进阶篇设计模式之十三——观察者模式和空对象模式

    简介 观察者模式又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependents)模式. ...

  3. java观察者模式异步notify_Java进阶篇设计模式之十三 ---- 观察者模式和空对象模式...

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  4. 【白话设计模式二十二】解释器模式(Interpreter)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  5. ES6 (二十二)Class 的继承、extends关键字、super 关键字(函数调用(constructor)、对象(父类原型对象))、原型对象(原型链)、Mixin 模式

    ES6 (二十二)Class 的继承.extends关键字.super 关键字(函数调用(constructor).对象(父类原型对象)).原型对象(原型链).Mixin 模式 文章目录 ES6 (二 ...

  6. 大话设计模式笔记(二十一、二十二、二十三、二十四、二十五、二十六)

    二十一.单例模式(Singleton) 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是 ...

  7. 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)

    备忘录模式 Memento 沿着脚印,走过你来时的路,回到原点. 苦海翻起爱恨 在世间难逃避命运 相亲竟不可接近 或我应该相信是缘份 一首<一生所爱>触动了多少人的心弦,一段五百年都没有结 ...

  8. Windows保护模式学习笔记(十二)—— 控制寄存器

    Windows保护模式学习笔记(十二)-- 控制寄存器 控制寄存器 Cr0寄存器 Cr2寄存器 Cr4寄存器 控制寄存器 描述: 控制寄存器有五个,分别是:Cr0 Cr1 Cr2 Cr3 Cr4 Cr ...

  9. (原创)无废话C#设计模式之二十二:总结(针对GOF23)

    无废话C#设计模式之二十二:总结(针对GOF23) 比较 设计模式 常用程度 适用层次 引入时机 结构复杂度 Abstract Factory 比较常用 应用级 设计时 比较复杂 Builder 一般 ...

最新文章

  1. Button的五种点击事件
  2. 用户态与内核态的区别
  3. 一个前端在校生的2018年终总结
  4. python中set函数是什么数据类型_阿博Python之路-详解Set数据类型
  5. 遮掩java_Java炸弹:重载、重写、隐藏、遮蔽、遮掩(2)
  6. 【转】ABP源码分析二十一:Feature
  7. RabbitMQ控制台详解
  8. 学员感言html效果图,学员感言丨非计算机专业学员 开始学HTML5的点点滴滴
  9. 高校表白app使用体验
  10. vue 手写 移动端 左右滑动 防止上下滑动冲突 超过宽度一半切换
  11. 12简单推导:切面条
  12. 操作系统原理,多道程序设计,并发环境与并发任务,进程定义,进程控制块PCB,PCB维护的进程数据
  13. debian 文件夹中文件大小_linux 查看文件和文件夹大小
  14. Electron入门——代码压缩与打包exe文件
  15. wmctf2022 两题PvsZ
  16. 【配置】Pycharm远程连接服务器、配置SSH、配置py环境
  17. [FJOI2016]建筑师
  18. GPGPU基础(二):GPGPU需要用到的OpenGL概念
  19. 【遇见大咖】测试界:你的年终奖有多少?
  20. 中英词典 mysql_英汉字典(含音标)csv导入MySQL

热门文章

  1. JPA、JTA与JMS
  2. Android 支付宝 移动支付接口 快速配置
  3. UIView的Touch事件UIControlEvents详解
  4. 开始使用 Markdown
  5. [新闻]炫目的全景与视频监控结合应用
  6. windows 编程随笔——输出文本WM_PAINT消息|有效矩形和无效矩形
  7. python课后题答案第二章_Python编程:从入门到实践——练习题答案(第二章)
  8. 敏捷开发你必须知道的7件事
  9. 4种语义分割数据集Cityscapes上SOTA方法总结
  10. 再拔头筹,FusionInsight为华为云大数据打造硬实力