空對象模式 (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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。