空对象设计模式(Null Object Design Pattern)

栏目: 后端 · 发布时间: 5年前

内容简介:在大多数面向对象的语言中,例如Java或C#,引用可能为null。在调用任何方法之前,需要检查这些引用以确保它们不为null,因为通常无法在空引用上调用方法。不使用空引用来表示对象的缺失(例如,不存在的客户),而是使用实现预期接口但其方法体为空的对象。这种方法优于工作默认实现的优点是Null对象是非常可预测的并且没有副作用:它什么都不做。

目的

在大多数面向对象的语言中,例如 Java 或C#,引用可能为null。在调用任何方法之前,需要检查这些引用以确保它们不为null,因为通常无法在空引用上调用方法。不使用空引用来表示对象的缺失(例如,不存在的客户),而是使用实现预期接口但其方法体为空的对象。这种方法优于工作默认实现的优点是Null对象是非常可预测的并且没有副作用:它什么都不做。

结构

空对象设计模式(Null Object Design Pattern)

参与者:

Client  

  • 需要合作者。

AbstractObject 

  • 声明Client的协作者的接口。
  • 根据需要,为所有类共有的接口实现默认行为。

RealObject

  • 定义AbstractObject的具体子类,其实例提供Client期望的有用行为。

NullObject

  • 提供与AbstractObject相同的接口,以便可以用空对象替换真实对象。
  • 实现其接口以不执行任何操作。什么都不做的确切含义取决于Client期望的行为类型。
  • 当有多个方法可以不做任何事情时,可能需要多个NullObject类。

合作

客户端使用AbstractObject类接口与其协作者进行交互。如果接收者是RealObject,则处理该请求以提供真实行为。如果接收者是NullObject,则通过不执行任何操作或至少提供空结果来处理请求。

源代码

空对象模式 用中性对象替换空值。很多时候,这简化了算法,因为不需要额外的空值检查。

在此示例中,我们构建了一个二叉树,其中节点是正常对象或空对象。树中没有使用空值,使遍历变得容易。

步骤1: 通过参考类图,让我们创建接口 -  节点 接口

<font><i>/**
 * 
 * Interface for binary tree node.
 *
 */</i></font><font>
<b>public</b> <b>interface</b> Node {

  String getName();

  <b>int</b> getTreeSize();

  Node getLeft();

  Node getRight();

  <b>void</b> walk();
}
</font>

步骤2: 为二叉树的普通节点创建实现。

<b>public</b> <b>class</b> NodeImpl implements Node {

  <b>private</b> <b>static</b> <b>final</b> Logger LOGGER = LoggerFactory.getLogger(NodeImpl.<b>class</b>);

  <b>private</b> <b>final</b> String name;
  <b>private</b> <b>final</b> Node left;
  <b>private</b> <b>final</b> Node right;

  <font><i>/**
   * Constructor
   */</i></font><font>
  <b>public</b> NodeImpl(String name, Node left, Node right) {
    <b>this</b>.name = name;
    <b>this</b>.left = left;
    <b>this</b>.right = right;
  }

  @Override
  <b>public</b> <b>int</b> getTreeSize() {
    <b>return</b> 1 + left.getTreeSize() + right.getTreeSize();
  }

  @Override
  <b>public</b> Node getLeft() {
    <b>return</b> left;
  }

  @Override
  <b>public</b> Node getRight() {
    <b>return</b> right;
  }

  @Override
  <b>public</b> String getName() {
    <b>return</b> name;
  }

  @Override
  <b>public</b> <b>void</b> walk() {
    LOGGER.info(name);
    <b>if</b> (left.getTreeSize() > 0) {
      left.walk();
    }
    <b>if</b> (right.getTreeSize() > 0) {
      right.walk();
    }
  }
}
</font>

步骤3:  二叉树节点的空对象实现。

实现为Singleton,因为所有NullNodes都是相同的。

<b>public</b> <b>final</b> <b>class</b> NullNode implements Node {

  <b>private</b> <b>static</b> NullNode instance = <b>new</b> NullNode();

  <b>private</b> NullNode() {}

  <b>public</b> <b>static</b> NullNode getInstance() {
    <b>return</b> instance;
  }

  @Override
  <b>public</b> <b>int</b> getTreeSize() {
    <b>return</b> 0;
  }

  @Override
  <b>public</b> Node getLeft() {
    <b>return</b> <b>null</b>;
  }

  @Override
  <b>public</b> Node getRight() {
    <b>return</b> <b>null</b>;
  }

  @Override
  <b>public</b> String getName() {
    <b>return</b> <b>null</b>;
  }

  @Override
  <b>public</b> <b>void</b> walk() {
    <font><i>// Do nothing</i></font><font>
  }
}
</font>

步骤4: 让我们使用客户端测试这个Null对象设计模式。

<b>public</b> <b>class</b> Client{
  <font><i>/**
   * Program entry point
   * 
   * @param args command line args
   */</i></font><font>
  <b>public</b> <b>static</b> <b>void</b> main(String[] args) {

    Node root =
        <b>new</b> NodeImpl(</font><font>"1"</font><font>, <b>new</b> NodeImpl(</font><font>"11"</font><font>, <b>new</b> NodeImpl(</font><font>"111"</font><font>, NullNode.getInstance(),
            NullNode.getInstance()), NullNode.getInstance()), <b>new</b> NodeImpl(</font><font>"12"</font><font>,
            NullNode.getInstance(), <b>new</b> NodeImpl(</font><font>"122"</font><font>, NullNode.getInstance(),
                NullNode.getInstance())));

    root.walk();
  }
}
</font>

输出:

适用性

使用Null对象模式时希望避免显式空检查并保持算法优雅且易于阅读。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你不是个玩意儿

你不是个玩意儿

杰伦·拉尼尔 / 葛仲君 / 中信出版社 / 2011-8 / 35.00元

“你不是个玩意儿。” 这句话当然不是骂人,这是一个宣言。人当然不是玩意儿,不是机器,而是人。 在网络化程度越来越高的今天,我们每个人似乎都有足够的理由,无限欣喜地拥抱互联网。然而,你有没有想过互联网那些不完美的设计却是某种潜在的威胁…… 为什么如此多的暴民在社交网站上争吵不休,很多骂人的脏话我们在现实的人际交往中可能从来不会使用,但在匿名网络环境中却漫天飞舞? 互联网的本质......一起来看看 《你不是个玩意儿》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具