安卓中的設(shè)計(jì)模式舉例

在講設(shè)計(jì)模式前,先通過講故事復(fù)習(xí)一遍

面向?qū)ο笤O(shè)計(jì)六原則

  • 單一職責(zé)原則,SRP(Single Responsibility Principle)
  • 開放-關(guān)閉原則,OCP(Open-Close Principle)
  • 里氏替換原則,LSP(Liskov Substitution Principle)
  • 接口隔離原則,ISP(Interface Segregation Principle)
  • 依賴倒置原則,DIP(Dependence Inversion Principle)
  • 最少知識原則,LKP(Least Knowledge Principle),又稱迪米特法則,LOD(Law Of Demeter)

故事來自《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)》,我壓縮了一下。這是本很好的書,把技術(shù)串進(jìn)了故事里,敘述角度很有創(chuàng)意。

小民寫一個圖片加載庫ImageLoader
第一版只用一個類實(shí)現(xiàn)圖片加載功能,并且能通過內(nèi)存緩存圖片。
業(yè)務(wù)都包含在一個類里導(dǎo)致代碼不易維護(hù)和擴(kuò)展。
所以在做第二版時依據(jù)SOLID原則和迪米特原則重構(gòu)項(xiàng)目

1.1 單一職責(zé)

劃分職責(zé),對代碼進(jìn)行模塊化和封裝,使得類結(jié)構(gòu)清晰。

依照這個原則,ImageLoader分成了ImageLoader類和ImageCache類
前者是圖片加載類,后者是圖片緩存類。這樣實(shí)現(xiàn)了一定程度的解耦。過了一段時間小民想優(yōu)化圖片緩存,比如加入SD卡緩存,讓用戶指定緩存位置等。但發(fā)現(xiàn)每次優(yōu)化圖片緩存,都需要改動ImageCache類。而既然ImageLoader中引用的ImageCache類,那么ImageCache類新增了一種特性,必然需要ImageLoader類也增加或者修改代碼才能使用這種特性。
這樣我們就進(jìn)入下一個原則。

1.2 開閉原則

對擴(kuò)展開放,對修改封閉。當(dāng)軟件需要變化時,應(yīng)該盡量通過擴(kuò)展的方式來實(shí)現(xiàn)變化,而不是通過修改已有的代碼。實(shí)現(xiàn)開閉原則的重要手段是通過抽象。

所以小民決定在ImageLoader中引用的ImageCache類改成ImageCache接口。
分別實(shí)現(xiàn)MemoryCache, DiskCache,DoubleCache來表示在內(nèi)存中緩存,在SD卡中緩存,以及兩者結(jié)合的雙緩存。

<center>ImageLoader UML 圖</center>

這里寫圖片描述

這樣只要接口的定義沒變,ImageLoader就不需要修改,如果想增加新的緩存方式,只需要寫一個新的類實(shí)現(xiàn)ImageCache接口,而且這樣客戶端也可以傳入自己實(shí)現(xiàn)的緩存類。
這樣的實(shí)現(xiàn)也符合里氏替換原則和依賴倒置原則。

1.3 里氏替換原則

所有引用基類的地方都能夠透明的使用其子類的對象。透明是指不需要關(guān)心子類的實(shí)現(xiàn),只要像使用父類一樣使用子類即可。

當(dāng)我們使用不同的ImageCache實(shí)現(xiàn)類時,ImageLoader不需要實(shí)現(xiàn)任何改動。

1.4 依賴倒置原則

模塊間的依賴通過抽象發(fā)生,實(shí)現(xiàn)類之間不發(fā)生直接的依賴關(guān)系,其依賴關(guān)系是通過接口或抽象類產(chǎn)生。

ImageLoader原來引用的是ImageCache類,小民改成了ImageCache接口,這樣ImageLoader就只依賴于抽象而不依賴具體的實(shí)現(xiàn)。

1.5 接口隔離原則

客戶端不應(yīng)該依賴它不需要的接口,依賴應(yīng)最小化。

比如我們的ImageCache接口只定義getCache 和 putCache兩個方法。依照接口隔離原則能降低類之類的耦合。

1.6 迪米特原則

一個對象應(yīng)該對其他對象有最少的了解。

比如小民最先采用wharton的DiskLruCache實(shí)現(xiàn)DiskCache,后來替換成了自己實(shí)現(xiàn)的SD卡緩存。但這些對客戶端都沒有影響,因?yàn)樘鎿Q是在DiskLruCache內(nèi)部完成的,客戶端只知道ImageCache的get 和 set 接口。

可以看出,遵循SOLID原則最重要的途徑是抽象 ,或者說面向接口編程

以上六原則可以作為判斷一個設(shè)計(jì)模式是否良好的標(biāo)準(zhǔn)。
設(shè)計(jì)模式是什么?
是對軟件設(shè)計(jì)中普遍存在的各種問題,所提出的可復(fù)用的解決思路。

<center>

</center>

設(shè)計(jì)模式的分類

創(chuàng)建型模式 Creation

結(jié)構(gòu)模式 Structure

行為模式 Behavior

創(chuàng)建型模式

抽象了對象實(shí)例化過程

  • 單例
    Application (每個程序有唯一的Application類,它的生命周期即此程序的生命周期)
    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
  • 工廠方法
    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)
  • **簡單工廠 **
    BitmapFactory.decodeFile(String path, Options opts)
  • 抽象工廠
    MediaPlayerFactory的實(shí)現(xiàn)類StagefrightPlayer NuPlayerFactory SonivoxPlayerFactory TestPlayerFactory 分別生成不同的MediaPlayerBase
  • 建造者 Builder
    AlertDialog.Builder
  • 原型Prototype
    用于在組件之間傳遞數(shù)據(jù)的Intent
結(jié)構(gòu)模式

描述如何將對象結(jié)合在一起形成更大的結(jié)構(gòu)

  • 適配器
    ListView 和 RecyclerView 的 Adapter(不同的view和不同的數(shù)據(jù)源,只要實(shí)現(xiàn)Adapter的規(guī)范,即可交互)
  • 橋接
    Window 與 WindowManager
  • 組合
    ViewGroup(各種炫酷的View =ViewGroupA+ViewGroupB+ViewC ViewGroupA=View+View+View )
  • 裝飾器
    ContextImpl和ContextWrapper
  • 享元
    查詢語句的編譯結(jié)果 SQLiteCompiledSql
  • 代理
    ActivityManagerProxy代理了ActivityManagerService的startActivity等功能
  • 外觀
    Media FrameWork(多媒體框架的實(shí)現(xiàn)需要多個底層library的協(xié)同工作,但多媒體開發(fā)者只需要熟悉android.media.MediaPlayer類,它已經(jīng)抽象出簡單友好的接口)

行為模式

涉及對象之間任務(wù)的分配以及完成這些任務(wù)的算法

  • 責(zé)任鏈
    屏幕點(diǎn)擊事件從父View傳遞到子View
  • 命令
    EventBus
  • 解釋器
    解析AndroidManifest.xml
  • 中介
    XXManagerService,WindowManagerService,InputManagerService,
    APP之間是跨進(jìn)程通信,通過Binder實(shí)現(xiàn)
  • 備忘錄
    Activity的onSaveInstanceState和onRestoreInstanceState
  • 觀察者
    Broadcast Receiver (廣播的訂閱和發(fā)布,發(fā)布者和接收者解耦,方便擴(kuò)展,從權(quán)限,時效到優(yōu)先級,都可高度定制)
  • 策略
    Android Animation中使用Interpolator
  • 模板
    Activity的生命周期
  • 狀態(tài)
    Wifi狀態(tài),數(shù)據(jù)連接狀態(tài),藍(lán)牙耳機(jī)狀態(tài)
  • 迭代器
    集合Collection實(shí)現(xiàn)了Iterable接口
  • 訪問者
    APT Dagger

Android中的架構(gòu)

MVC (Model View Controller)
MVP (Model View Presenter)

  • MVC模型
這里寫圖片描述
  • MVP模型
這里寫圖片描述
  • MVC 和 MVP 的區(qū)別
這里寫圖片描述

然而,在實(shí)踐MVP時,發(fā)現(xiàn)Presenter的接口的粒度在組員間很難恰當(dāng)并且一致的把握。粒度小了臃腫,大了又不夠解耦。
之后發(fā)現(xiàn)MVVM結(jié)合Data Binding庫的情況下,粒度的問題就沒那么明顯,因?yàn)樽詣咏壎ǖ臋C(jī)制免去了很多代碼,使得代碼簡介而靈活。


這里寫圖片描述

MVV圖示如上,實(shí)線表示必然的聯(lián)系,虛線表示可能的聯(lián)系。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容