Null空对象模式

更新日期: 2019-03-21阅读: 2.2k标签: null

概述

在这个快速教程中,我们将看一下Null对象模式,这是设计模式的一个特例,一个经常被我们遗忘的特例。我们将描述它的目的以及我们何时应该考虑使用它。

像往常一样,我们还将提供一个简单的代码示例。


空对象模式

在大多数面向对象的编程语言中,我们会考虑不进行null引用,为此我们经常被迫写空检查:
Command cmd = getCommand();
if (cmd != null) {
    cmd.execute();
}

有时,如果此类if语句的数量变多,则代码的可读性会变得很差,难以阅读且容易出错。这是Null对象模式可以派上用场的时候。

Null对象模式的目的是最小化这种空检查。相反,我们可以识别null行为并将其封装在客户端代码所期望的类中。这样我们就不再需要处理空引用的特殊处理。

我们可以简单地处理null对象,就像处理实际包含一些更复杂的业务逻辑的给定类型的任何其他实例一样,以此来保持代码的清洁。

由于null对象不应具有任何状态,因此无需多次创建相同的实例。因此,我们经常将null对象实现为单例


Null Object Pattern的UML图

让我们直观地看一下模式:

模式图

我们可以看到,会有以下参与者:

  • 客户端需要AbstractObject的实例
  • AbstractObject定义客户期望的执行逻辑- 它还可以包含实现类的共享逻辑
  • RealObject实现了AbstractObject并提供了真实的行为
  • NullObject实现AbstractObject并提供do nothing行为


案例

现在我们已经清楚地了解了这个理论,让我们看一个例子。

假设一个场景,有一个消息路由器模块。每条消息都应分配有效的优先级。我们的系统应该将高优先级消息路由到SMS网关,而具有中等优先级的消息应该路由到JMS队列。

但是,有时会出现“未定义”或空优先级的消息。这些消息应该从进一步处理中丢弃。

首先,我们将创建路由器接口:

public interface Router {
    void route(Message msg);
}

接下来,让我们创建上述接口的两个实现 - 负责路由到SMS网关的接口以及将消息路由到JMS队列的接口:

public class SmsRouter implements Router {
    @Override
    public void route(Message msg) {
        // implementation details
    }
}
public class JmsRouter implements Router {
    @Override
    public void route(Message msg) {
        // implementation details
    }
}

最后,让我们实现我们的null对象

public class NullRouter implements Router {
    @Override
    public void route(Message msg) {
        // do nothing
    }
}

我们现在准备将所有部分组合在一起。让我们看看示例客户端代码的外观如何:

public class RoutingHandler {
    public void handle(Iterable<Message> messages) {
        for (Message msg : messages) {
            Router router = RouterFactory.getRouterForMessage(msg);
            router.route(msg);
        }
    }
}

我们可以看到,无论RouterFactory返回什么实现,我们都以相同的方式处理所有Router对象。这使我们能够保持代码的清洁和可读性。


何时使用空对象模式

我们应该使用Null对象模式,否则客户端会检查null只是为了跳过执行或执行默认操作。 在这种情况下,我们可以将do nothing逻辑封装在空对象中,并将其返回给客户端而不是空值。这样,如果给定实例为null,则客户端代码不再需要知道 。

这种方法也遵循一般的面向对象原则。

为了更好地理解何时应该使用Null对象模式,让我们假设我们必须实现CustomerDao接口,定义如下:

public interface CustomerDao {
    Collection<Customer> findByNameAndLastname(String name, String lastname);
    Customer getById(Long id);
}

如果没有客户匹配提供的搜索条件,

大多数开发人员将从findByNameAndLastname()返回Collections.emptyList()。这是遵循Null对象模式的一个很好的例子。 相反,getById()应返回具有给定id的客户。调用此方法的人希望获得特定的客户实体。如果不存在这样的客户,我们应该显式返回null以表示提供的ID存在问题。

与所有其他模式一样,我们需要在盲目实现Null对象模式之前考虑我们的特定用例。否则,我们可能会无意中在代码中引入一些很难找到的错误。


结论

在本文中,我们了解了Null对象模式是什么以及何时可以使用它。我们还实现了一个设计模式的简单示例。

来自:https://segmentfault.com/a/1190000018600865


链接: https://fly63.com/article/detial/2454

Js中Undefined和Null

js中一共有5种简单数据类型:Undefined, Null, boolean, Number, String. 还有一种复杂的数据类型:Object,本篇主要介绍Undefined和Null

js中的null和undefined

null和undefined属于js中两种不同的基本数据类型,都可以表示“没有”,含义非常相似。将一个变量赋值为undefined或null,老实说,语法效果几乎没区别。并且在if语句的判断条件中,它们都会自动转为false

JS中的空值

尽管从第一次遇到空值引起的bug开始,我就一直要求自己注意空值,但还是经常犯这样的错误,JS中的空值真的需要多加注意。这里说的空值包括undefined和null

解决Js中处理null和undefined的麻烦事

许多 JavaScript 开发人员正在为怎么处理可选值头痛。有什么好办法来最大程度地减少由值(可能为 null、undefined或在运行时未初始化)引起的错误?在某些情况下,一些语言具有内置功能。在某些静态类型的语言中

关于null>=0为true

我们今天讨论的主要内容,并不是这个结果可能看起来多么奇怪. 而是为什么会这样. 之所以特别记一篇随笔在这里,主要是因为,我在得到了 Brendan Eich 的一些确认后.发现答案和我当初的猜测不一样

Js中undefined和null的区别是什么

在JavaScript中值undefined和null都表示”无”,那么它们之间有什么区别?undefined:在 JavaScript 中, undefined 是一个没有设置值的变量。typeof 一个没有值的变量会返回 undefined。null是一个只有一个值的特殊类型。表示一个空对象引用。

JavaScript 中 undefined 与 null 的用法区别

大多数计算机语言,有且仅有一个表示“无”的值,比如:C 语言的 NULL,Java 语言的 null,Python 语言的 None,Ruby 语言的 nil。但是在 JavaScript 中却同时存在 undefined 和 null

关于 JavaScript 中 null 的一切

JavaScript 有两种类型:原始类型(strings, booleans, numbers, symbols)和对象,对象是一个复杂的数据结构。最简单的 JavaScript 对象是普通对象 —— 键和相关值的集合

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!