在Joshua Bloch很有名的一本书《Effective in java》中建议不要在代码中返回空的collection/map/array,就像下面的代码一样:

public List<String> returnCollection() {
//remainder omitted
if (/*some condition*/) {
return null;
} else {
// return collection
}
} 而应该使用下面的模式:
public List<String> returnCollection() {
//remainder omitted
if (/*some condition*/) {
return Collections.emptyList();
} else {
// return collection
}
} 这种模式可以防止像下面这种方式调用你的代码抛出null pointer
  1. if (obj.returnCollection().size() > 0) {  
  2. // remainder omitted  

在Robert C. Martin《敏捷软件开发,原则,模式,实践》一书中给了一个类似的模式,它包含了所有的对象,不仅仅只针对collections/maps/arrays。这个模式被称作Null Object。

这里有一个实例,假定你有一个应用程序需要检查用户是否认证过。

public class User {
private String username;
private boolean authenticated;
// remainder omitted public boolean isAuthenticated() {
return authenticated;
}
// remainder omitted
} 代码像下面这样返回一个User对象的引用,
public User getUser() {
if (/*some condition*/) {
return user;
} else {
return null;
}
} 这种方式下,检查User是否认证过需要用下面的代码才可以: if (obj.getUser() != null && obj.getUser().isAuthenticated() {
        // allow  
}
// remainder omitted
上面检查对象是否为空并不只是一个样板代码,当你忘记检查对象是否为null时,就会引起bug. 这里Null Object 模式可以帮助你:
public class NullUser extends User {

    public static final NullUser INSTANCE = new NullUser();

    public static NullUser getInstance() {
return INSTANCE;
} @Override
public boolean isAuthenticated() {
return false;
} private NullUser() {
}
}
public User getUser() {
if (/*some condition*/) {
return user;
} else {
return NullUser.getInstance();
}
}

if (obj.getUser().isAuthenticated() {
// allow
}
// remainder omitted

我发现这种模式确实很管用,它避免了很多的Null pointer异常。这里仍然有一个问题,User应用是一个类还应该是一个接口;NullUser是继承一个基类还是实现一个接口,把这个问题留给你去

考虑。

你是如何思考Null Object模式的?

翻译自:http://blog.bielu.com/2008/12/null-object-design-pattern.html

转载请注明出处。





 
 

 

Null Pointer --设计模式的更多相关文章

  1. c/c++ 重载 数组 操作符[] operator[ is ambiguous, as 0 also mean a null pointer of const char* type.

    // Note: //int x = a[0].GetInt(); // Error: operator[ is ambiguous, as 0 also mean a null pointer of ...

  2. differences between null pointer and void pointer.

    These are two different concepts, you cannot compare them. What the difference between the skunk and ...

  3. leetcode 编译问题:Line x: member access within null pointer of type 'struct TreeNode'

    参考: LEETCODE 中的member access within null pointer of type 'struct ListNode' 解决 leetcode 编译问题:Line x: ...

  4. A pointer is a variable whose value is the address of another variable 指针 null pointer 空指针 内存地址0 空指针检验

    小结: 1.指针的实际值为代表内存地址的16进制数: 2.不同指针的区别是他们指向的变量.常量的类型: https://www.tutorialspoint.com/cprogramming/c_po ...

  5. 力扣 报错 runtime error: load of null pointer of type 'const int'

    runtime error: load of null pointer of type 'const int' 要求返回的是int* 解决方案 1.指针使用malloc分配空间 用 int * p = ...

  6. Unable to handle kernel NULL pointer dereference at virtual address 00000000问题的解决

    今天在编译好内核模块后,安装内核模块memdev.ko的时候,出现了Unable to handle kernel NULL pointer dereference at virtual addres ...

  7. Unable to handle kernel NULL pointer dereference at virtual address 00000000【转】

    本文转载自:https://blog.csdn.net/hpu11/article/details/72628052 这说明是非法指针的使用,才导致系统出错. [ 1023.510000] Unabl ...

  8. spring quartz job autowired 出错 null pointer

    什么情况下才能用autowired? 当当前类属于spring IOC容器管时候就可以,比如在applicationContext.xml里有定义 就是说在spring上下文里能够找到 但是比如qua ...

  9. java NPE就是空指针异常,null pointer exception

    java NPE就是空指针异常,null pointer exception

随机推荐

  1. 教程-MessageBox 使用方法

    对应对象:TApplication 声明:function MessageBox(Text,Caption:PChar;Flags:Word):Integer; 功能:MessageBox方法可以显示 ...

  2. JavaScript- The Good Parts Chapter 5 Inheritance

    Divides one thing entire to many objects;Like perspectives, which rightly gazed uponShow nothing but ...

  3. org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.

    该问题已经困扰了我很多天 问题终于解决了,全局变量导致的,碰到这种问题很难再自己本身的机器上发现错误,所以,应该看一下自己写的方法是否涉及到了全局变量出现不一致的情况,让其统一即可.

  4. Android 入门第一课 一个简单的提示框

    1.打开Android开发环境Eclipse来到主界面 2.新建一个安卓项目 File->New->Android Application project 在上面有红色错误的地方填上应用程 ...

  5. ubuntu安装软件

    sudo apt-get install gnome-tweak-tool sudo apt-get install gksu 软件数据库损坏 无法安装或删除任何软件.请先使用新立得软件包管理器或在终 ...

  6. socket编程——一个简单的样例

    从一个简单的使用TCP样例開始socket编程,其基本过程例如以下: server                                                  client ++ ...

  7. java19 先开服务器,再开客户端

    先开服务器,再开客户端. import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOExcep ...

  8. lambda显式声明返回值

    10.21 编写一个lambda,捕获一个局部int变量,并递减变量值,直至它变为0.一旦变量变为0,再调用lambda应该不再递减变量.lambda应该返回一个bool值,指出捕获的变量是否为0. ...

  9. 从源码角度深入分析ant

    Ant的基本概念 首先是ant的基本概念:Project,Target,Tasks,Properties,Paths 1.Project <project> build.xml文件最顶层的 ...

  10. AFNetworking源码分析

    来源:zongmumask 链接:http://www.jianshu.com/p/8eac5b1975de 简述 在iOS开发中,与直接使用苹果框架中提供的NSURLConnection或NSURL ...