本次编码的时候犯了一个愚蠢的错误,在几乎所有的biz和manager层加了一个public static final String NULL = null;以此来作为统一的空对象,而这个完全是多次一举,因为null就可以直接代替,就此看来自己完全没有一点点面向对象的概念。为了防止犯类似的错 误,决定查询资料好好讨论一下null Object的使用。

1:返回一个空的域对象而不是null;
在基于领域模型的设计中,在底层定义的domain Object在数据库查询的时候可以返回为空,在此我们先定义一个Do对象。
public class Tree{
  private Integer height;
  private Integer age;
  private String name;
  private Double diameter;
  //树叶的域对象;
  private Leaves leaves;
  // get set methods……
}
2:在DAO层封装和数据库交互的基本方法后,我们在business层开始对业务逻辑进行简单的封装。当我们提供一个findTree的方法的时候,如果在数据库中查询一个年龄为16岁的tree对象为空,一般的情况下我们返回为null对象,这样就会导致程序在要取值的时候必须判断是否为空,实例如下:
public class TreeBiz{
  public Tree findTree(Tree tree){
    //在这个地方思考一下,如果返回的tree为空的话,下面的方法调用的问题;
    // treeDao.findTree(tree)…… 
  } 
  public String treeName(Tree tree){
      return tree.getName();
  }
}
3:如果获取的tree对象为空的话,就会报空指正的错误。所以必须加上if(tree != null)……而这样就会导致程序中过多的判断了空,不够简洁,同时也很容易出错。
如果我们在域对象中重新定义一个空的对象,然后在dao层封装一下,代码的健壮性就会增强了很多。示例如下:
public class Tree{
  //增加一个空的tree对象
  public static final Tree NULL = new Tree();
  private Integer height;
  private Integer age;
  private String name;
  private Double diameter;
  //树叶的域对象;
  private Leaves leaves;
  // get set methods……
}
4:在DAO层封装一下获取tree对象的方法
public class TreeDao{
  public Tree findTree(Tree tree){ 
    Tree tree = …… 
  if(tree == null){
    //返回一个空的Tree对象
    return Tree.NULL;
  }else{
    return tree;
}
}
}
这样在业务逻辑层调用TreeDao方法的时候就很不会出现对象空指针的问题,增强了程序的健壮性。
有人或许会问,为什么在为空的时候不直接 new Tree(), 首先:new一个对象需要分配新的内存开销,而static final的NULL对象则在内存中有一块无法改变的存储空间,降低了系统的开销;其次,NULL对象在执行期就被初始化,返回NULL只用指向该内存地 址,而不是重新分配地址,提高的性能。
使用NULL Object模式可以确保在DAO层返回有效的对象,及时在查询失败的时候也是如此。这些代表失败的对象“什么也没有做”!