庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

谈NullObject模式

Posted on 2007-07-31 17:48 dennis 阅读(5148) 评论(7)  编辑  收藏 所属分类: 模式与架构
    知道这个模式还是通过《重构》,这个模式的出现还是了为了解决代码重复的坏味道。在项目中很经常见到类似下面这样的代码:
if(prj.getProjectId==null)
    plan.setCost(
0.0);
else
    plan.setCost(prj.getCost());

   我们在很多地方有类似的检查对象是否为null,如果为null,需要一个默认值等等这样的场景。显然,代码重复是坏味道,怎么消除这个坏味道呢?答案就是使用NullObject替代之,Null Object继承原对象。
class NullProject extends Project{
   
public boolean isNull(){
      
return true;
   }
}
class Project{
   
private double cost;
   
private String projectId;
   .
   
public boolean isNull(){
        
return false;
   }
}

那么,原来的代码可以改写为:
if(prj.isNull())
    plan.setCost(
0.0);
else
    plan.setCost(prj.getCost());

    如果Null Object的引入仅仅是带来这个好处,似乎没有理由让我们多敲这么多键盘。问题的关键是类似上面这样的判断也许出现在很多处,那么有价值的技巧出现了,我们在NullObject覆写getCost,提供缺省值:
class NullProject extends Project{
   
public boolean isNull(){
      
return true;
   }
   
public double getCost(){
      
return 0.0;      
   }
}
    因此,检查对象是否为null的代码可以去掉if...else了:
plan.setCost(prj.getCost());

    请注意,只有那些大多数客户端代码都要求null object做出相同响应时,这样的行为才有意义。比如我们这里当工程id为null,很多地方要求费用就默认为0.0。 特殊的行为我们仍然使用isNull进行判断。
    当然,另外在需要返回NullObject的地方,你应该创建一个null object以替代一般的对象,我们可以建立一个工厂方法:

class Project{
   
private double cost;
   
private String projectId;
   .
   
public boolean isNull(){
        
return false;
   }
   
public Project createNullProject(){
        
return new NullProject();
   }
}

   Null Object模式带来的好处:减少了检查对象是否为null的代码重复,提高了代码的可读性,通常这些Null Object也可以为单元测试带来简便。


评论

# re: 谈NullObject模式[未登录]  回复  更多评论   

2007-07-31 23:47 by xmlspy
很早以前用过这个模式,不过感觉实在没有必要
很麻烦

# re: 谈NullObject模式  回复  更多评论   

2007-08-01 07:48 by dennis
@xmlspy
如果只是少数地方有这样的条件判断,我也认为实在没有必要,不过在我们项目的场景中,赋予默认值以及check null经常出现,因此使用此模式后确实大幅度减少了重复代码,取舍之间就看大家自己判断

# re: 谈NullObject模式  回复  更多评论   

2007-08-01 09:25 by dreamstone
对于长业务流程,多个条件分支的情况下还是挺有用的。
记得曾经做过一个报文解析系统,当时我为了遍历树不为空做过一个类似的结构。

# re: 谈NullObject模式  回复  更多评论   

2007-08-01 11:31 by 金大为
我想,我们常常用的 Collections.EMPTY_LIST之类的空列表,空map。
和这里说的NullObject算是同一类技巧吧。

# re: 谈NullObject模式  回复  更多评论   

2007-08-01 13:43 by dennis
@金大为
有点类似的味道,java的collection框架真是模式大集合

# re: 谈NullObject模式  回复  更多评论   

2007-08-03 09:35 by 一名
这是故意让null作为一种值来传递时候用的吧?如果我在数据库查询时候,出现异常,or映射的框架返回的null对象,那怎么办?不是还是要判断是否为null的情况吗?

# re: 谈NullObject模式  回复  更多评论   

2007-08-03 09:43 by dennis
@一名
这时候你应当返回一个NullObject,而不是一般的Object。这个模式有一定的适用场景,请看文中所述

只有注册用户登录后才能发表评论。


网站导航: