爲了程序的健壯性,咱們可使用空對象模式

空對象模式 (null object Pattern)是一種軟件設計模式。能夠用於返回無心義的對象時,它能夠承擔處理null的責任。有時候空對象也被視爲一種設計模式。java

在寫代碼的時候咱們常常會遇到空指針,爲了不空指針的發生須要作一些判斷。若是是複雜對象的話,還須要一層層地去判斷。這個時候我就無比懷念groovy、kotlin這類語言。能夠使用形如:設計模式

user?.address?.name

這樣的語法糖,而無需一層層的判斷。ide

google的guava庫提供了Optional類,能夠有效的判斷null對象。svg

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

guava能夠建立指定的null對象post

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

在java 8中也新增了Optional類。this

同時,我本身也仿照guava的Optional類寫了一個簡化版的Optional並附上使用方法,它藉助了rxjava。google

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();
    }
}

上面講了那麼多,是爲了防止空指針出現,如今咱們來看看空對象模式具體的使用場景吧,假設咱們在代碼中使用了鏈式調用,形如:url

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

只要某一個環節出現問題,就會有空指針的隱患的。好比RestClient的post()方法內部出現了問題,那就很是嚴重了,後面整個鏈路都會斷掉,報空指針異常。spa

那咱們如何保證整個鏈路不斷呢?在post()方法裏面會調用一個getConnection()方法.net

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哈哈~

本文同步分享在 博客「fengzhizi715」(JianShu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索