在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. Spring Framework 5.0.0.M3中文文档 翻译记录 introduction

    翻译自: http://docs.spring.io/spring/docs/5.0.0.M3/spring-framework-reference/htmlsingle/#spring.tld.ha ...

  2. Python递归遍历目录下所有文件

    #自定义函数: import ospath="D:\\Temp_del\\a"def gci (path): """this is a stateme ...

  3. 获取WINDOWS特殊文件夹

    const// registry entries for special paths are kept in :  REGSTR_PATH_SPECIAL_FOLDERS   = REGSTR_PAT ...

  4. [Javascript] Fetch API

    fetch() does the same thing as XHR, but fetch return a promise. fetch('password.txt', { 'method': 'P ...

  5. springmvc 双亲上下文导致的 No mapping found for HTTP request

    今天搭建spring mvc ,结果发出请求总是No mapping found for HTTP request with URI [******] 于是开始排查了半天,后来在网上搜到了双亲上下文的 ...

  6. Android(java)学习笔记162:Android启动过程(转载)

    转载路径为: http://blog.jobbole.com/67931/ 1. 关于Android启动过程的问题: 当按下Android设备电源键时究竟发生了什么? Android的启动过程是怎么样 ...

  7. Java Inner class

    2016-03-27 内部类:就是把一个类的定义放在另外一个外围类定义的里面. class OutterClass{ class InnerClass { } } 1. 内部类主要有四种:成员内部类( ...

  8. jQuery 序列化表单 serialize() serializeArray()

    1.serialize()方法 格式:var data = $("form").serialize(); 功能:将表单内容序列化成一个字符串. 这样在ajax提交表单数据时,就不用 ...

  9. Sql 随机生成日期时间

    DECLARE @dt1 DATETIME,@dt2 DATETIME,@a BIGINT,@b BIGINT SET @dt1='2010-01-01'--开始日期 SET @dt2='2010-0 ...

  10. Struts,Spring,Hibernate的作用

    Spring的作用: 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因 为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL ...