Employee e = DB.getEmployee("Bob"); //判断雇员e是否应该今天发薪水,如果是,则发 if(e != null && e.isTimeToPay(today)) e.pay();
如果Bob对象不存在,e就是一个null,然后&&的第一个表达式会被首先求值,而仅当第一个表达式为true时才会对第二个表达式求值。而在很多情况下我们会忘 了对null进行检查判定。这种惯用方法虽然常见,但很丑陋。
通过用DB抛出一个异常而不是返回null可以减少出错的可能。不过try/catch块更加丑陋,所以我们可以用Null Object模式来解决这个问题。
Employee e = DB.getEmployee("Bob"); //判断雇员e是否应该今天发薪水,如果是,则发 if(e.isTimeToPay(today)) e.pay();
public class DB{ public static Employee getEmployee(String name){ Emplyee e = Sql.get(name);//从数据库中得到该name的对象 if(e == null) return Employee.NULL; return e; } }
public interface Employee{ public void pay(); public boolean isTimeToPay(Date payDate); public static final Employee NULL = new Employee(){ public boolean isTimeToPay(Date payDate){ return false; } public void pay(){ } } }
使用无效的雇员类成为一个匿名内部内是一个确保该类只有单一实例的方法。实际上并不存在NullEmployee类本身。其他任何人都无法创建无效雇员类的其他实例。
如果可以创建无效雇员类的多个实例,那么这种表达方式是不可靠的。