接口隔離原則英文全稱是Interface Segregation Principle,縮寫是ISP。
ISP的定義是:客戶端不應(yīng)該依賴它不需要的接口。另一種定義是:類間的依賴關(guān)系應(yīng)該建立在最小的接口上。接口隔離原則將非常龐大、臃腫的接口拆分成更小具體的接口,這樣客戶講會只需要知道他們感興趣的方法。接口隔離原則的目的是系統(tǒng)解開耦合,從而容易重構(gòu)、更改和重新部署。
接口隔離原則說白了就是,讓客戶端依賴的接口盡可能的小,這樣說可能還有點抽象,我們一一個示例來說明一下。在此之前我們來說一個場景,在Java6以及之前的JDK版本中,有一個非常討厭的問題,那就是在使用了OutputStream或者其他可關(guān)閉的對象之后,我們必須保證它們最終被關(guān)閉了,我們的SD卡緩存類中就有這樣的代碼:
/**
* 將圖片存入SD卡中
* @param url
* @param bitmap
*/
public void put(String url,Bitmap bitmap) {
FileOutputStream out = null;
try {
out = new FileOutputStream(CACHE_DIR + url);
bitmap.compress(Bitmap.CompressFormat.PNG,100,out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
這段代碼的可讀性非常差,各種try...catch嵌套的都是簡單的代碼,但是會嚴重影響代碼的可讀性,并且多層級的大括號很容易將代碼寫到錯誤的層級中。我們對這類代碼也非常反感,下面來看看如何解決這類問題。
我們可能知道Java中有一個Closeable接口,該接口標(biāo)識了一個可關(guān)閉的對象,它只有一個close方法,我們要講的FileOutputStream類就實現(xiàn)類就實現(xiàn)了這個接口,實際上還有100多個類實現(xiàn)了這還接口,這意味著,在關(guān)閉著100多個類型的對象時,都需要寫出像put方法中finally代碼段那樣的代碼。這是非常讓人痛苦的,所以我們要把這個問題變得簡單,既然都是實現(xiàn)了Closeable接口,那只要我建一個方法統(tǒng)一來關(guān)閉這些對象不就可以了嗎,于是我們開始寫下如下的工具類:
public class CloseUtils {
/**
*關(guān)閉Closeable對象
**/
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我們看看把這段代碼運用到上述的put方法中的效果如何:
public void put(String url,Bitmap bitmap) {
FileOutputStream out = null;
try {
out = new FileOutputStream(CACHE_DIR + url);
bitmap.compress(Bitmap.CompressFormat.PNG,100,out);
} catch (Exception e) {
e.printStackTrace();
} finally {
CloseUtils.closeQuietly(out);
}
}
代碼簡潔了很多,而且這個工具類可以運用到各類可關(guān)閉的對象中,保證了代碼的重用性。
CloseUtils的closeQuitely方法的基本原理就是依賴于Closeable抽象而不是具體實現(xiàn)(這不是依賴倒置原則么?),并且建立在最小化依賴原則的基礎(chǔ)上,它只需要知道這個對象是可關(guān)閉的,其他的一概不關(guān)心,也就是這里所介紹的接口隔離原則。
優(yōu)點:
- 降低耦合性
- 提高代碼的可讀性
- 隱藏實現(xiàn)細節(jié)