为了程序的健壮性,我们可以使用空对象模式

简介: 为了程序的健壮性,我们可以使用空对象模式

空对象模式 (null object Pattern)是一种软件设计模式。可以用于返回无意义的对象时,它可以承担处理null的责任。有时候空对象也被视为一种设计模式。


在写代码的时候我们经常会遇到空指针,为了避免空指针的发生需要做一些判断。如果是复杂对象的话,还需要一层层地去判断。这个时候我就无比怀念groovy、kotlin这类语言。可以使用形如:

user?.address?.name


这样的语法糖,而无需一层层的判断。

google的guava库提供了Optional类,可以有效的判断null对象。

Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5


guava可以创建指定的null对象

Optional<Integer> nullable=Optional.fromNullable(null);
System.out.println("from Nullable Optional isPresent:"+nullable.isPresent());  //returns from Nullable Optional isPresent:false


在java 8中也新增了Optional类。


同时,我自己也仿照guava的Optional类写了一个简化版的Optional并附上使用方法,它借助了rxjava。

import rx.Observable;
/**
 * 使用方法:
 *      String s = null;
 *      Optional.ofNullable(s).orElse("default")); // 如果s为null,则显示default,否则显示s的值
 * @author Tony Shen
 *
 */
public class Optional<T> {
    Observable<T> obs;
    public Optional(Observable<T> obs) {
        this.obs = obs;
    }
    public static <T> Optional<T> of(T value) {
        if (value == null) {
            throw new NullPointerException();
        } else {
            return new Optional<T>(Observable.just(value));
        }
    }
    public static <T> Optional<T> ofNullable(T value) {
        if (value == null) {
            return new Optional<T>(Observable.<T>empty());
        } else {
            return new Optional<T>(Observable.just(value));
        }
    }
    public T get() {
        return obs.toBlocking().single();
    }
    public T orElse(T defaultValue) {
        return obs.defaultIfEmpty(defaultValue).toBlocking().single();
    }
}


上面讲了那么多,是为了防止空指针出现,现在我们来看看空对象模式具体的使用场景吧,假设我们在代码中使用了链式调用,形如:

client = RestClient.post(request.getUrl())
        .readTimeout(request.getReadTimeoutMillis())
        .connectTimeout(request.getConnectTimeoutMillis())
        .addHeaders(request.getHeaders());


只要某一个环节出现问题,就会有空指针的隐患的。比如RestClient的post()方法内部出


现了问题,那就非常严重了,后面整个链路都会断掉,报空指针异常。


那我们如何保证整个链路不断呢?在post()方法里面会调用一个getConnection()方法

public HttpURLConnection getConnection() {
        if (connection == null)
            connection = createConnection();
        if (connection == null) {
            clientIsNull = true;
            connection = NullConnection.createNull(url);
        }
        return connection;
    }


请注意,在getConnection()方法里会有两个connection == null的判断。理论上,第一次调用createConnection()方法时,connection是不会为空的。但是在使用某个APM sdk时,确实发现有极少的概率connection会为空。如果它为空,那么我们在第二个判断中增加了如下的代码,来保证返回的connection不为null,提高程序的健壮性。

connection = NullConnection.createNull(url);


我们来看看,NullConnection是怎么回事

/**
 * Created by Tony Shen on 2016/12/6.
 */
public class NullConnection extends HttpURLConnection {
    private NullConnection(URL url) {
        super(url);
    }
    @Override
    public void disconnect() {
    }
    @Override
    public boolean usingProxy() {
        return false;
    }
    @Override
    public void connect() throws IOException {
    }
    public boolean isNull() {
        return true;
    }
    public static NullConnection createNull(URL url) {
        return new NullConnection(url);
    }
}


其实,基本没做啥事,主要多了一个createNull()的方法。它会产生一个NullConnection对象,它的作用是防止产生null,从而保证原先的RestClient链路是正常的。这就是空对象模式。


链式调用,会让代码更加清晰,带给我们的好处是非常明显的。只要我们处理好空指针的隐患,就可以更愉悦地写代码了O(∩_∩)O哈哈~

相关文章
|
22天前
|
存储 网络协议 搜索推荐
宏函数的代码替换机制会对程序的可移植性产生什么影响
宏函数的代码替换机制可能导致程序可移植性降低,因为它在预处理阶段直接替换文本,可能引发类型不匹配、副作用等问题,不同编译器和平台表现不一。
|
2月前
|
Java 调度
代码打造每日任务系统
在游戏开发中,每日任务系统对提升玩家活跃度和留存率至关重要。通过Java的面向对象特性,可将每日任务抽象为`Task`类,并通过实例化及方法调用实现任务创建、执行与奖励功能。进一步,可以创建`DailyTaskSystem`类来管理所有每日任务,包括添加、删除和获取任务列表等操作。这种设计不仅简化了任务管理,还增强了游戏的可玩性和吸引力。更多细节和实现方法可见相关游戏逻辑设计与具体需求。
39 0
|
4月前
|
存储 缓存 Java
java枚举消除冗余代码问题之findByName和findByValue方法工作时的问题如何解决
java枚举消除冗余代码问题之findByName和findByValue方法工作时的问题如何解决
|
4月前
|
存储
代码优化设计问题之当方法体只有一行时,独立存在的方法的必要性开始存疑问题如何解决
代码优化设计问题之当方法体只有一行时,独立存在的方法的必要性开始存疑问题如何解决
|
6月前
|
设计模式 缓存 安全
单例模式的应用与陷阱:确保你的代码只有一个实例
单例模式的应用与陷阱:确保你的代码只有一个实例
187 0
|
4月前
|
JSON 前端开发 Java
代码的应用重构问题之BaseActivity类的主要功能问题如何解决代码缩减的主要问题如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决代码缩减的主要问题如何解决
|
6月前
|
存储 Java API
掌握8条方法设计规则,设计优雅健壮的Java方法
掌握8条方法设计规则,设计优雅健壮的Java方法
|
6月前
|
SQL NoSQL Java
系统干崩了,只认代码不认人
为了保障系统的高可用和稳定,我发誓以后只认代码不认人。文末总结了几个小教训,希望对你有帮助。
系统干崩了,只认代码不认人
|
消息中间件 JavaScript 小程序
这些老系统代码,是猪写的么?
这些老系统代码,是猪写的么?
|
安全 Java API
了解程序运行逻辑的必要性及应用和硬件的关系
了解程序运行逻辑的必要性及应用和硬件的关系
111 0