一扶檐、火警報警器
假設(shè)有一組火警報警系統(tǒng),由三個子元件構(gòu)成:一個警報器瓦糕,一個噴水器底洗,一個自動撥打電話的裝置。其抽象如下:
class AlarmSensor:
def run(self):
print "Alarm Ring..."
class WaterSprinker:
def run(self):
print "Spray Water..."
class EmergencyDialer:
def run(self):
print "Dial 119..."
在業(yè)務(wù)中如果需要將三個部件啟動咕娄,例如亥揖,如果有一個煙霧傳感器,檢測到了煙霧圣勒。在業(yè)務(wù)環(huán)境中需要做如下操作:
if __name__=="__main__":
alarm_sensor=AlarmSensor()
water_sprinker=WaterSprinker()
emergency_dialer=EmergencyDialer()
alarm_sensor.run()
water_sprinker.run()
emergency_dialer.run()
但如果在多個業(yè)務(wù)場景中需要啟動三個部件费变,怎么辦?Ctrl+C加上Ctrl+V么圣贸?當(dāng)然可以這樣挚歧,但作為碼農(nóng)的基本修養(yǎng)之一,減少重復(fù)代碼是應(yīng)該會被很輕易想到的方法旁趟。這樣昼激,需要將其進(jìn)行封裝,在設(shè)計模式中锡搜,被封裝成的新對象橙困,叫做門面。門面構(gòu)建如下:
class EmergencyFacade:
def __init__(self):
self.alarm_sensor=AlarmSensor()
self.water_sprinker=WaterSprinker()
self.emergency_dialer=EmergencyDialer()
def runAll(self):
self.alarm_sensor.run()
self.water_sprinker.run()
self.emergency_dialer.run()
這樣耕餐,業(yè)務(wù)場景中這樣寫就可以了:
if __name__=="__main__":
emergency_facade=EmergencyFacade()
emergency_facade.runAll()
打印如下:
Alarm Ring...
Spray Water...
Dial 119...
二凡傅、門面模式
門面模式也叫外觀模式,定義如下:要求一個子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個統(tǒng)一的對象進(jìn)行肠缔。門面模式提供一個高層次的接口夏跷,使得子系統(tǒng)更易于使用。門面模式注重“統(tǒng)一的對象”明未,也就是提供一個訪問子系統(tǒng)的接口槽华。門面模式與之前說過的模板模式有類似的地方,都是對一些需要重復(fù)方法的封裝趟妥。但從本質(zhì)上來說猫态,是不同的。模板模式是對類本身的方法的封裝,其被封裝的方法也可以單獨使用亲雪;而門面模式勇凭,是對子系統(tǒng)的封裝,其被封裝的接口理論上是不會被單獨提出來用的义辕。
三虾标、門面模式的優(yōu)點和使用場景
優(yōu)點:
1、減少了系統(tǒng)之間的相互依賴灌砖,提高了系統(tǒng)的靈活璧函;
2、提高了整體系統(tǒng)的安全性:封裝起的系統(tǒng)對外的接口才可以用周崭,隱藏了很多內(nèi)部接口細(xì)節(jié)柳譬,若方法不允許使用,則在門面中可以進(jìn)行靈活控制续镇。
使用場景:
1美澳、為一個復(fù)雜的子系統(tǒng)提供一個外界訪問的接口。這類例子是生活還是蠻常見的摸航,例如電視遙控器的抽象模型制跟,電信運營商的用戶交互設(shè)備等;
2酱虎、需要簡化操作界面時雨膨。例如常見的扁平化系統(tǒng)操作界面等,在生活中和工業(yè)中都很常見读串。
四聊记、門面模式的缺點
1、門面模式的缺點在于恢暖,不符合開閉原則排监,一旦系統(tǒng)成形后需要修改,幾乎只能重寫門面代碼杰捂,這比繼承或者覆寫等方式舆床,或者其它一些符合開閉原則的模式風(fēng)險都會大一些。