Null Pointer --设计模式

在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

转载请注明出处。



 
 

 
时间: 2024-10-06 13:07:01

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

differences between null pointer and void pointer.

These are two different concepts, you cannot compare them. What the difference between the skunk and the moonlight? Null pointer is a special reserved value of a pointer. A pointer of any type has such a reserved value. Formally, each specific pointe

kernel panic 分析(NULL pointer dereference)

It is another typical kernel panic due to invalid address. Panic log: [ 20.896935] c3 554 (netd) Unable to handle kernel NULL pointer dereference at virtual address 00000012 [ 20.906200] c3 554 (netd) pgd = ffffffc02f746000 [ 20.910793] c3 554 (netd)

debug---null Pointer Exception--一步步查找(2)

添加PartyLocationRepository后,再次在Ubuntu中编译项目,再次报空指针异常. 直接在createDto处打断点,然后debug每个表达式的值,找出来到底是哪个为null. 经过分析,发现是this.getConverter()为null,而这个Converter是和PartyLocationEntity以及PartyLocationDto对应的.因此,这里还需要写个PartyLocationEntity和PartyLocationDto关联的PartyLocationC

NULL Pointer Dereference(转)

0x00 漏洞代码 null_dereference.c: #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> void (*my_funptr)(void); int bug1_write(struct file *file, const char *buf, unsigned long len) { m

Eclipse 代码检测报 Potential null pointer access: The variable XX may be null at this location

对于这种本来是挺好的一功能,瞬间感觉好强大啊有木有,还会自动帮你检测空指针. 可是在看别人代码,或者服务器代码的时候就蛋疼了啊!这不改编译就过不了啊! 其实如果想去掉这种检测非常简单.一个设置的问题. Eclipse-->Window-->preferences-->java-->Compiler-->Errors/Warnings,找到下面这个选项 看到了吗?把Error改成warning 将项目重新clean 一下.OK!

JS原型+原型链+设计模式

JavaScript是一种基于对象的语言,JavaScript中的所有对象,都具有prototype属性.prototype属性返回对象的所有属性和方法,所有 JavaScript 内部对象都有只读的 prototype 属性,可以向其原型中动态添加属性和方法,但该对象不能被赋予不同的原型.但是自定义的对象可以被赋给新的原型. 对象分为函数对象和普通对象,区分:凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象.(Object ,Function 是JS自带的函数

iOS 关于nil和Nil及null与&lt;null&gt;的区别

问题是这样的. NSDictionary *sample = [NSJSONSerialization JSONObjectWithData:received options:NSJSONReadingMutableLeaves error:&error]; NSString *messageInfo = [sample objectForKey:@"message"]; sample是一个字典,messsageInfo是从字典中根据key值取得的,然后通过log可以知道mes

C++中Reference与指针(Pointer)的使用对比

我们已经知道在C++中,对象变量直接存储的是对象的值.这是与Java不同的,在Java中对象变量存储的是一个地址,该地址指向对象值实际存储的地方.有时在C++中也需要实现这样的布置,这就用到了指针pointer.在 C++中,一个指向对象的变量叫做指针.如果T是一种数据类型,则 T* 是指向这种数据类型的指针. 这里重点介绍C++与Java的不同,要详细了解C++中指针的使用 就像 Java中一样,一个指针变量可以被初始化为空值 NULL,另外一个指针变量的值,或者一个调用new生成的新对象:

【转载】C/C++杂记:NULL与0的区别、nullptr的来历

原文:C/C++杂记:NULL与0的区别.nullptr的来历 某些时候,我们需要将指针赋值为空指针,以防止野指针. 有人喜欢使用NULL作为空指针常量使用,例如:int* p = NULL;. 也有人直接使用0值作为空指针常量,例如:int* p = 0;. 前者可能觉得:NULL作为空指针常量,名字很形象,可读性较强. 后者可能觉得:NULL并不是C/C++语言的关键字,而是一个在标准库头文件<stddef.h>中定义的宏,因此要使用NULL,可能需要直接或简介地包含<stddef.