面向?qū)ο缶幊痰牧笤瓌t
讓項(xiàng)目擁有變化的能力--依賴倒置原則
依賴倒置原則的英文全程是Dependence Inversion Principle,縮寫是DIP咒彤,依賴倒置原則是一種特定的解耦形式三妈,使得高層次的模塊不依賴于低層次的模塊的實(shí)現(xiàn)細(xì)節(jié)的目的姨涡,依賴模塊被顛倒了先蒋。簡(jiǎn)單的說有以下幾點(diǎn):
- 高層模塊不應(yīng)該依賴于底層模塊职恳,兩者都應(yīng)該依賴于其抽象揩尸。
- 抽象不應(yīng)該依賴于細(xì)節(jié)蛹屿。
- 細(xì)節(jié)應(yīng)該依賴于抽象。
在Java語言中岩榆,抽象就是指接口和抽象類错负,兩者都是不能直接被實(shí)例化的;細(xì)節(jié)就是指實(shí)現(xiàn)類勇边,實(shí)現(xiàn)接口或繼承抽象類而產(chǎn)生的類就是細(xì)節(jié)犹撒,細(xì)節(jié)可以被直接實(shí)例化。高層模塊是指調(diào)用端粒褒,低層模塊就是具體實(shí)現(xiàn)類识颊。依賴倒置原則在Java中的表現(xiàn)就是:模塊間的依賴通過抽象發(fā)生,實(shí)現(xiàn)類之間不發(fā)生直接的依賴關(guān)系奕坟,其依賴關(guān)系是通過接口或者抽象類產(chǎn)生的祥款。
在我們之前的章節(jié)中,有一章的ImageLoader是依賴于具體實(shí)現(xiàn)的月杉,代碼如下:
public class ImageLoader {
// 內(nèi)存緩存(直接依賴于細(xì)節(jié))
MemoryCache mMemoryCache = new MemoryCache ();
// 線程池刃跛,線程數(shù)為CPU所允許的數(shù)量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
//加載圖片到ImageView中
public void displayImg(final String url, final ImageView imageView) {
}
//從網(wǎng)絡(luò)獲取圖片
private Bitmap downloadImg(String imageUrl) {
}
}
然后我們分析出該圖片加載類只有內(nèi)存緩存,已經(jīng)無法滿足我們的需求苛萎,于是我們?cè)O(shè)計(jì)出了DoubleCache類桨昙,此時(shí)便需要修改我們的代碼:
public class ImageLoader {
// 雙緩存(直接依賴于細(xì)節(jié))
DoubleCache mDoubleCache = new DoubleCache ();
// 線程池,線程數(shù)為CPU所允許的數(shù)量
ExecutorService mExecutorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
//加載圖片到ImageView中
public void displayImg(final String url, final ImageView imageView) {
}
//從網(wǎng)絡(luò)獲取圖片
private Bitmap downloadImg(String imageUrl) {
}
}
我們將MemoryCache修改為DoubleCache腌歉,并且修改了部分緩存代碼蛙酪,就輕松地滿足了我們的需求。但是翘盖!這里就違反了我們第二章所講的開閉原則桂塞,這樣設(shè)計(jì)出來的代碼在后期需求改變時(shí)需要不停地修改,會(huì)使代碼冗余并且容易出錯(cuò)最仑。我們?cè)?a href="http://www.reibang.com/p/fd1f130b4791" target="_blank">開閉原則一章結(jié)束時(shí)的代碼就很好地解決了這個(gè)問題藐俺,一句話概括起來就是:依賴抽象,而不依賴于具體實(shí)現(xiàn)泥彤。通過依賴注入的方式欲芹,可以保證系統(tǒng)的靈活性,我們回顧一下之前的代碼(不熟悉的同學(xué)請(qǐng)回頭閱讀開閉原則:
ImageCache抽象類
public interface ImageCache {
Bitmap get(String url);
void put(String url,Bitmap bitmap);
}
ImageLoader類
public class ImageLoader {
// 圖片緩存吟吝,依賴于抽象菱父,并且有一個(gè)默認(rèn)的實(shí)現(xiàn)
ImageCache mImageCache = new MemoryCache();
// 設(shè)置緩存策略,依賴于抽象
public void setmImageCache(ImageCache cache){
mImageCache = cache;
}
public void displayImage(String imageUrl,ImageView imageView){
}
}
在這里,我們建立了ImageCache抽象浙宜,并且讓ImageLoader依賴于抽象而不是具體細(xì)節(jié)官辽。當(dāng)我們的緩存策略發(fā)生改變時(shí),我們只需要實(shí)現(xiàn)ImageCache或者集成已有的ImageCache子類完成具體的代碼實(shí)現(xiàn)即可粟瞬,這樣就保證了我們的軟件的高拓展性同仆,有了變化的能力,這就是依賴倒置原則裙品。
從上述的幾節(jié)我們也發(fā)現(xiàn)俗批,好像要讓系統(tǒng)變得靈活,抽象似乎成了我們唯一的手段市怎。