8-Python與設計模式–門面模式
一、火警報警器(1)
假設有一組火警報警系統,由三個子元件構成:一個警報器,一個噴水器,
一個自動撥打電話的裝置。其抽象如下:
class AlarmSensor:def run(self):print "Alarm Ring..."
class WaterSprinker:def run(self):print "Spray Water..."
class EmergencyDialer:def run(self):print "Dial 119..."
在業務中如果需要將三個部件啟動,例如,如果有一個煙霧傳感器,檢測到了煙霧。
在業務環境中需要做如下操作:
if __name__=="__main__":alarm_sensor=AlarmSensor()water_sprinker=WaterSprinker()emergency_dialer=EmergencyDialer()alarm_sensor.run()water_sprinker.run()emergency_dialer.run()
但如果在多個業務場景中需要啟動三個部件,怎么辦?Ctrl+C加上Ctrl+V么?
當然可以這樣,但作為碼農的基本修養之一,減少重復代碼是應該會被很輕易想到的方法。這樣,需要將其進行封裝,在設計模式中,被封裝成的新對象,叫做門面。
門面構建如下:
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()
這樣,業務場景中這樣寫就可以了:
if __name__=="__main__":emergency_facade=EmergencyFacade()emergency_facade.runAll()
打印如下:
Alarm Ring… Spray Water… Dial 119…
二、門面模式
門面模式也叫外觀模式,定義如下:要求一個子系統的外部與其內部的通信必須通過一個統一的對象進行。
門面模式提供一個高層次的接口,使得子系統更易于使用。門面模式注重“統一的對象”,也就是提供一個訪問
子系統的接口。門面模式與之前說過的模板模式有類似的地方,都是對一些需要重復方法的封裝。
但從本質上來說,是不同的。模板模式是對類本身的方法的封裝,其被封裝的方法也可以單獨使用;
而門面模式,是對子系統的封裝,其被封裝的接口理論上是不會被單獨提出來用的。
三、門面模式的優點和使用場景
優點:
1、減少了系統之間的相互依賴,提高了系統的靈活;
2、提高了整體系統的安全性:封裝起的系統對外的接口才可以用,隱藏了很多內部接口細節,若方法不允許使用,則在門面中可以進行靈活控制。使用場景:
1、為一個復雜的子系統提供一個外界訪問的接口。這類例子是生活還是蠻常見的,例如電視遙控器的抽象模型,電信運營商的用戶交互設備等;
2、需要簡化操作界面時。例如常見的扁平化系統操作界面等,在生活中和工業中都很常見。
四、門面模式的缺點
1、門面模式的缺點在于,不符合開閉原則,一旦系統成形后需要修改,幾乎只能重寫門面代碼,
這比繼承或者覆寫等方式,或者其它一些符合開閉原則的模式風險都會大一些。