1、 什么是Null对象模式?为什么要采用Null对象?

个人理解,所谓模式就是程序员们在编程的时候对一些类似问题总结出的通用解决方法或思路。因此,即使你的问题非常吻合某种设计模式所对应的问题,也不能指望现有的某种设计模式能够完全解决我们编程中的具体设计问题。

闲言少述,进入正题:

Null对象模式,顾名思义就是一种空的对象,它什么都不干。

或许你要问:既然它什么都不干,那要它干嘛?且看下面这个null对象的经典例子:

代码段1:

Employee e = DB.getEmployee();
If(null == e && e.isTimeToPay(today))e.pay();

例子中,需要判断对象是否为null然后采用不同的动作,即是否支付薪水;如果你的程序中有很多判断“null == e”这样的东西,根据Martin Fowler在《重构》一书中的说法便是你的代码中有了坏的味道,需要搞掉它!!!!

如果采用了Null对象之后,由于DB.getEmployee()返回的Null对象与Employee对象的具有相同的接口,当返回了Null对象之后也可以使用代码段2,只是这时空对象什么都没有操作,上述代码就可以简化为:

代码段2:

Employee e = DB.getEmployee();
If(e.isTimeToPay(today))e.pay();

在程序开发中诸如此类问题有很多,例如下面这段增加avl树节点的函数代码,其功能为在一个avl树种增加一个节点(节点类的接口为IAVLNode,实现类为AVLNode),函数中首先判断根节点是否为空,如果为空则将新增节点设为根节点,否则找到合适的位置将新增节点插入。

代码段3:

//为根节点{avlRoot = addNode;return;}IAVLNode curNode = avlRoot;IAVLNode parentNode = avlRoot;while(null != curNode){parentNode = curNode;          if(curNode.getValue() < addNode.getValue())curNode = curNode.getRightChild();elsecurNode = curNode.getLeftChild();}if(parentNode.getValue()< addNode.getValue())parentNode.setRightChild(addNode);elseparentNode.setLeftChild(addNode);addNode.setParentNode(parentNode);}

在上面的一个函数代码中就有两处需要判断节点是否为空的操作,很显然,如果你要写一个AVL树旋转(就是在平衡二叉搜索树种增加节点后的四种调整平衡的操作,即左左插入时需右旋,右右插入时需左旋,左右插入时需左右两次旋转,右左插入时需要右左两次旋转)的代码,你的代码中判断节点是否为空的操作会有很多!!!!!

 2、 如何定义和使用Null对象?

继续接着第1节的avl树的例子说明一下如何定义和使用Null对象,尤其注意,在实际操作中可采用的实现方式有很多种,本文只是说明其中一个,不要为此而禁锢了自己的思维。

Null对象只需要一个,因此这里采用了单例模式,具体定义如下:

代码段4:

public class NullNode implements IAVLNode {private static NullNode nullObj= null;private NullNode(){}public static NullNode GetNullObj(){if(null == nullObj)nullObj = new NullNode();return nullObj;}@Overridepublic boolean isNullObj() {// TODO Auto-generated method stubreturn true;}@Overridepublic void DisplayInfo() {}@Overridepublic IAVLNode getParentNode() {return null;}@Overridepublic void setParentNode(IAVLNode parentNode) {}@Overridepublic int getValue() {return 0;}@Overridepublic void setValue(int value) {}@Overridepublic IAVLNode getLeftChild() {return null;}@Overridepublic void setLeftChild(IAVLNode leftChild) {}@Overridepublic IAVLNode getRightChild() {return null;}@Overridepublic void setRightChild(IAVLNode rightChild) {}@Overridepublic int getDepth() {return 0;}@Overridepublic void setDepth(int depth) {}@Overridepublic boolean isBalance() {return true;}
}

在该Null对象中,继承自了接口IAVLNode,实现了该接口的所有操作,但这些操作什么都没有干。

 3、 Null对象还有哪些不足?

1)   本文开始时说到Null对象主要解决问题之一就是程序中大量对null的判断;可是在实际应用中,并不是所有的诸如“null == avlRoot”之类的代码都能够全部去掉,部分情况下确实需要判断对象是否为空的时候依然需要调用“avlRoot.isNull”。

2)   有些时候空对象的空函数实现起来比较困难,例如在代码段3中的getValue()函数,这里就不太好确定让Null对象的该函数返回什么值,在代码段4中让它返回了0,如果我在程序中需要比较节点之间值的大小,这时空对象返回的0值就不恰当了。

Null对象模式的用法相关推荐

  1. 设计模式笔记二十二:空对象模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出.欢迎一起讨论. 在空对象模式(Null Object Pattern)中,一个空对象取代 ...

  2. Java数据访问对象模式

    数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来.以下是数据访问对象模式的参与者. 数据访问对象接 ...

  3. Java Data Access Object Pattern(数据访问对象模式)

    数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来.以下是数据访问对象模式的参与者. 数据访问对象接 ...

  4. php7 空对象,PHP设计模式之空对象模式(Null Object)代码实例大全(26)

    目的 空对象模式不属于 GoF 设计模式,但是它作为一种经常出现的套路足以被视为设计模式.它具有如下优点: 客户端代码简单 可以减少报空指针异常的几率 测试用例不需要考虑太多条件 返回一个对象或 nu ...

  5. junit5_JUnit 5和Selenium –使用Selenium内置的`PageFactory`实现页面对象模式

    junit5 Selenium是一组支持浏览器自动化的工具和库,主要用于Web应用程序测试. Selenium的组件之一是Selenium WebDriver,它提供客户端库,JSON有线协议(与浏览 ...

  6. java中正则全局匹配_JS中正则表达式全局匹配模式/g用法实例

    JS中正则表达式全局匹配模式 /g用法详解 本文章来详细介绍js中正则表达式的全局匹配模式 /g用法, var str = "123#abc"; var re = /abc/ig; ...

  7. 设计模式のNullObjectPattern(空对象模式)----行为模式

    一.产生背景 在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查.Null 对象不是检查空值,而是反应一个不做任何动作的关系.这样的 Null 对象也可 ...

  8. PHP设计模式--数据访问对象模式

    最简单的Web部件和最复杂的在线电子商务Web站点具有一个共同点:它们都要处理数据.大量的编程都设计数据的访问和操作.随着Internet的发展.脸颊存储设备应用数据的大量增长.对分析论的更深入理解以 ...

  9. idea内置junit5_JUnit 5和Selenium –使用Selenium内置的`PageFactory`实现页面对象模式

    idea内置junit5 Selenium是一组支持浏览器自动化的工具和库,主要用于Web应用程序测试. Selenium的组件之一是Selenium WebDriver,它提供客户端库,JSON有线 ...

最新文章

  1. mysql数据库表格怎么建立_mysql数据库表格怎么建立
  2. AB1601 PWM模块
  3. Linux selinux入门
  4. 【收藏】搭载nfs是客户端新建操作出现read only file system
  5. flatmap和map的区别!
  6. git 提示 error setting certificate verify locations !解决
  7. Spring Data JDBC通用DAO实现–迄今为止最轻量的ORM
  8. HBase-存储-HFile格式
  9. 海康威视4G球机对接萤石云平台实现实时预览、云台控制 ----- java完整demo
  10. android开发的小程序,一份基于Android平台系统下初学者开发的微信小程序的新
  11. 单元测试报告软件测试,软件单元测试报告-模板
  12. Excel学习笔记4||数据处理函数ROUND、INT、TRUNC、MAX、MIN、ROW、COLUMN
  13. 又是一年双11,神棍节终于来啦
  14. 安卓学习 Day18:利用单选按钮实现底部导航条
  15. Vue3有哪些不向下兼容的改变
  16. 利用 Django 动态展示 Pyecharts 图表数据的几种方法
  17. java开源验证框架OVAL
  18. 断言(assert)方法
  19. 怎么让DIV的高度为浏览器高度
  20. 客快物流大数据项目(七十四):Impala的java开发

热门文章

  1. alias cli3 配置_vue-cli3项目搭建配置以及性能优化
  2. 【python基础知识】对文本数据库的一些基本操作
  3. html绘制word柱状图,word如何制作柱状图
  4. python制作物联网控制软件下载_Python+树莓派制作IoT(物联网)门控设备
  5. 虚拟linux系统首次登入,第一次在虚拟机启动我们的Linux系统
  6. python清除实例化类_在Python中,如何尝试(和排除)类的实例化?
  7. java调用ole ie_SWT中通过Automatioin的方式访问IE(升级版)
  8. php 窗体移动,窗体处理 - My Labs! PHP - PHP博客
  9. idea 设置jdk_IDEA开发小技巧~jdk问题
  10. c 窗体中添加mysql控件,MYSQL 统计数据-svn服务器启动-WinFrom控件库|.net开源控件库|HZHControls官网...