Facade模式在開發(fā)中使用的頻率非常高央勒,比如我們在使用一些第三方SDK庫的時候,他們基本都是使用了外觀模式澳化。
外觀模式非常簡單崔步,就是在我們功能具體實現(xiàn)的類上面建立一個統(tǒng)一的類來讓客戶端使用,而不用暴露具體每個類的細(xì)節(jié)缎谷。
定義:
要求一個子系統(tǒng)外部和內(nèi)部的通訊通過一個統(tǒng)一的對象來進(jìn)行井濒,提供了一個高層次的接口,使得子系統(tǒng)更加易用列林。
使用場景:
1.為一個復(fù)雜的子系統(tǒng)提供一個簡單的接口瑞你。子系統(tǒng)往往會不斷演化,而變得復(fù)雜希痴、多變者甲。
外觀模式隱藏了子系統(tǒng)的細(xì)節(jié),我們只要關(guān)心統(tǒng)一個接口類就行了砌创,隱藏了子系統(tǒng)的具體實現(xiàn)虏缸,隔離了變化。
2.當(dāng)需要構(gòu)建一個層次結(jié)構(gòu)的子系統(tǒng)時嫩实,可以讓子系統(tǒng)通過Facade通信刽辙,從而簡化了他們之間的依賴關(guān)系。
實現(xiàn):
比如現(xiàn)在的智能手機有很多功能甲献,拍照宰缤,電話,運行軟件晃洒,短信等慨灭。
我們以拍照和電話為例子。
有兩個系統(tǒng)類球及,PhoneImpl和CameraImpl
PhoneImpl中有dail缘挑,hangup方法
CameraImpl有open、takePicture桶略、takeVedio方法
如果我們要去視頻通話的時候,就需要用到PhoneImpl.dail和CameraImpl.open、CameraImpl.takeVedio方法际歼,讓客戶端來操作的話會很麻煩惶翻。
于是我們使用一個外觀類MobilePhone,里面有一個VedioChat方法鹅心,方法調(diào)用了PhoneImpl.dail和CameraImpl.open吕粗、CameraImpl.takeVedio,客戶端只要去使用MobilePhone中的VedioChat方法就行了旭愧。
Android中的實現(xiàn)
我們在使用Activity的時候颅筋,常常用到startActivity、sendBroadcast输枯、getResources议泵、getPackageManager等類似的方法,其實這里Activity更像是一個代理類桃熄,這些方法內(nèi)部是調(diào)用了mBase.xxxXX方法先口,這里的mBase就是context的具體實現(xiàn)ContextImpl類對象。
而ContextImpl類里面對這些方法的具體實現(xiàn)其實也不是自身實現(xiàn)的瞳收,就比如startActivity方法碉京,其實是調(diào)用了mMainThread.getInstrumentation().exeStartActivity。
所以這里的ContextImpl類其實就是一個外觀類螟深,他本身并沒有實現(xiàn)具體的方法谐宙,而是保存了很多子系統(tǒng)對象,當(dāng)用戶調(diào)用一個方法時界弧,其實是調(diào)用了這些子系統(tǒng)對象的方法凡蜻。
這樣使得用戶不用去關(guān)心具體是那個對象實現(xiàn)了哪些方法,使用更為便捷了夹纫。
再來舉幾個里面方法的例子:
sendBroadcast其實是調(diào)用了:
ActivityManagerNative.getDefault().broadcastIntent
registerReceiverInternal調(diào)用了:
ActivityManagerNative.getDefault().registerReveiver
startService調(diào)用了:
ActivityManagerNative.getDefault()咽瓷。
setWallpaper調(diào)用了
getWallpaperManager().setBitmap(bitmap)
優(yōu)點:
1.對客戶端隱藏了子細(xì)節(jié),減少了客戶端對于子系統(tǒng)的耦合舰讹,擁抱變化
2.外觀類對子系統(tǒng)的接口封裝茅姜,使得系統(tǒng)更加易于使用
缺點:
1.外觀類的接口膨脹,增加了使用成本
2.外觀類沒有遵循開閉原則月匣,當(dāng)子系統(tǒng)業(yè)務(wù)發(fā)生變化時钻洒,就要去修改外觀類。