门面模式(Facade Pattern)

1 代码

假设有一组火警报警系统,由三个子元件构成:一个警报器,一个喷水器,一个自动拨打电话的装置。其抽象如下:


In [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...")

在业务中如果需要将三个部件启动,例如,如果有一个烟雾传感器,检测到了烟雾。在业务环境中需要做如下操作:


In [2]:
alarm_sensor = AlarmSensor()
water_sprinker = WaterSprinker()
emergency_dialer = EmergencyDialer()
alarm_sensor.run()
water_sprinker.run()
emergency_dialer.run()


Alarm Ring...
Spray Water...
Dial 119...

但如果在多个业务场景中需要启动三个部件,怎么办?Ctrl+C加上Ctrl+V么?当然可以这样,但作为码农的基本修养之一,减少重复代码是应该会被很轻易想到的方法。这样,需要将其进行封装,在设计模式中,被封装成的新对象,叫做门面。门面构建如下


In [3]:
class EmergencyFacade(object):
    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()

In [4]:
emergency_facade=EmergencyFacade()
emergency_facade.runAll()


Alarm Ring...
Spray Water...
Dial 119...

2 Description

门面模式也叫外观模式,定义如下:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。门面模式注重“统一的对象”,也就是提供一个访问子系统的接口。门面模式与之前说过的模板模式有类似的地方,都是对一些需要重复方法的封装。

3 Advantages

  • 减少了系统之间的相互依赖,提高了系统的灵活
  • 提高了整体系统的安全性

4 Usages

  • 为一个复杂的子系统提供一个外界访问的接口
  • 需要简化操作界面时

5 Disadvantages

  • 不符合开闭原则,一旦系统成形后需要修改,几乎只能重写门面代码,