面向?qū)ο蟮牧笤瓌t之里氏替換原則
學(xué)習(xí)了何紅輝、關(guān)愛民寫的《Android設(shè)計模式》,對于面向?qū)ο蟮牧笤瓌t有進一步的理解,特此根據(jù)自己的理解記錄總結(jié)一下
什么是里氏替換原則
面向?qū)ο蟮恼Z言有三大特性:封裝、繼承、多態(tài),里氏替換原則就是依賴于繼承、多態(tài)這兩大特性,它的原則就是只要父類能出現(xiàn)的地方子類就能出現(xiàn),而且不會報錯,但是子類能出現(xiàn)的地方,父類不一定能出現(xiàn),術(shù)語就是 —— 抽象。
在上一篇《面向?qū)ο蟮牧笤瓌t之 —— 開閉原則》中我們說了要讓程序可擴展,其實開閉原則跟里氏替換原則是不離不棄的,它們兩個基本都是同時出現(xiàn)。
在上一篇中,ImageLoader類通過依靠ImageCache實現(xiàn)圖片緩存,而ImageCache只是一個接口,真正的實現(xiàn)還需要通過實現(xiàn)ImageCache接口進行具體的業(yè)務(wù)邏輯的實現(xiàn),比如內(nèi)存緩存MemoryCache、sd卡緩存DiskCache、雙緩存DoubleCache,而用戶需要自定義實現(xiàn)緩存方式,可以通過實現(xiàn)ImageCache接口進行具體的實現(xiàn),這讓ImageLoader充滿了無限的可能性。
在以上的邏輯中,其實已經(jīng)很好的體現(xiàn)了里氏替換原則,我們想一下如果ImageLoader類中的setImageCache(ImageCache imageCache),這個imageCache不能夠被子類替換的話,那用戶如何設(shè)置不同的緩存對象, 也完全不能自定義實現(xiàn)緩存方式,通過《面向?qū)ο蟮牧笤瓌t之 —— 開閉原則》中的if{}()else()來判斷使用什么樣的緩存方式嗎?
/**?
?????*?顯示圖片?
?????*?@param?url?圖片的url?
?????*?@param?imageView?要顯示的view?
?????*/??
????public?void?displayImage(final?String?url,?final?ImageView?imageView)?{??
????????Bitmap?bitmap=null;??
????????if(isUseDoubleCache()){??
????????????bitmap=doubleCache.get(url);??
????????}else?if(isUseDiskCache()){??
????????????bitmap=diskCache.get(url);??
????????}else{??
????????????bitmap=imageCache.get(url);??
????????} ?
這顯然是不可行的,而里氏替換原則就是為這類問題提供指導(dǎo)原則,即建立抽象,通過抽象建立規(guī)范,我們的ImageCache用的是接口,其實是一樣的,因為接口也是一種規(guī)范,我們通過實現(xiàn)了ImageCache接口達到不同的緩存策略,具體的實現(xiàn)在運行的時候進行設(shè)置:
ImageLoader?imageLoader=new?ImageLoader();??
????????/**?
?????????*?內(nèi)存緩存方式?
?????????*/??
????????imageLoader.setImageCache(new?MemoryCache());??
????????/**?
?????????*?SD卡緩存方式?
?????????*/??
????????imageLoader.setImageCache(new?DiskCache());??
????????/**?
?????????*?雙緩存方式?
?????????*/??
????????imageLoader.setImageCache(new?DoubleCache());??
????????/**?
?????????*?自定義緩存方式?
?????????*/??
????????imageLoader.setImageCache(new?ImageCache()?{??
????????????@Override??
????????????public?void?put(String?url,?Bitmap?bitmap)?{??
????????????????//用戶自定義的緩存方式??
????????????}??
??
????????????@Override??
????????????public?Bitmap?get(String?url)?{??
????????????????//從緩存中獲取圖片??
????????????????return?null;??
????????????}??
????????}); ?
所以,利用開閉原則跟里氏替換原則來達到對擴展開發(fā),對修改封閉的效果,這兩個原則都強調(diào)了一個OOP的重要特性——抽象,所以在開發(fā)中,靈活運用抽象,是讓代碼優(yōu)化的重要一步。