在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
- if (obj.returnCollection().size() > 0) {
- // 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