结构型——外观模式

外观模式

外观模式是一种将复杂的子系统抽象出一个简化的统一接口以供客户端使用的结构型设计模式。他的核心思想就是化繁为简,隐藏子系统的内部复杂性,降低客户端与子系统的耦合性。

特点

  • 简化接口:将多个子系统的交互抽象为外观类中的方法接口。
  • 解耦:客户端与子系统之间解耦,客户端只需与外观类交互,无需了解子系统的细节。
  • 分层设计:外观类可作为中间层,将复杂的子系统进行逻辑分组,便于管理。

模式结构

角色 描述
外观类 (Facade) 提供客户端与子系统交互的接口,内部协调多个子系统的交互工作
子系统类 (Subsystems) 封装复杂业务逻辑,提供外观类调用的接口

简单示例

class Light:                                 # 子系统类1
    def turn_on(self):
        return "Light is on"

    def turn_off(self):
        return "Light is off"

class AirConditioner:                        # 子系统类2
    def turn_on(self):
        return "Air conditioner is on"
    
    def turn_off(self):
        return "Air conditioner is off"

class MusicPlayer:                           # 子系统类3
    def play_song(self, song):
        return f"Playing song: {song}"
    
    def stop_song(self):
        return "Stopping music"

class SmartHomeFacade:                       # 外观类
    def __init__(self):
        self._light = Light()
        self._air_conditioner = AirConditioner()
        self._music_player = MusicPlayer()
        

    def home_mode(self):
        result = []
        result.append(self._light.turn_on())
        result.append(self._air_conditioner.turn_on())
        result.append(self._music_player.play_song("New World"))
        return "\n".join(result)

    def sleep_mode(self):
        result = []
        result.append(self._light.turn_off())
        result.append(self._music_player.stop_song())
        reutrn "\n".join(result)


# 客户端使用
if __name__ == "__main__":
    smart_home = SmartHomeFacade()
    # 打开智能家居在家模式
    print(smart_home.home_mode())
    # 打开智能家居睡觉模式
    print(smart_home.sleep_mode())

    # 输出结果
    # 打开智能家居在家模式
    # Light is on
    # Air conditioner is on
    # Playing song: New World
    # 打开智能家居睡觉模式
    # Light is off
    # Stopping music

适用场景

  1. 整合复杂子系统:当一个系统需要提供多个功能,但是每个功能都由多个类来完成时,可以使用外观模式来简化系统的使用。
  2. 封装第三方库或者遗留代码:使用外观类封装第三方库或遗留代码提供统一的对外接口。
  3. 分层架构:在多层架构中,可以使用外观模式来隐藏底层细节,只暴露最外层的接口。
  4. 简化测试流程:在测试过程中,可以使用外观模式来简化测试流程,减少测试代码量。
  5. 其实外观模式在python的日常使用中随处可见
    subprocess库,既通过run()接口封装下面的进程创建、管道管理等子系统操作;
    logging库,既通过basicConfig()接口封装下面的日志配置、日志输出等子系统操作;
    requests库,既通过get()post()等接口封装下面的网络请求、会话管理、代理设置等子系统操作;
    SQLAlchemy库,既通过create_engine()sessionmaker()等接口封装下面的数据库连接、会话管理、查询等子系统操作。

优缺点

  • 优点:
    • 解耦客户端,也解耦子系统。
    • 简化接口调用
  • 缺点
    • 外观类的维护成本高,需要维护多个子系统的接口。
    • 引入了额外的复杂度,需要了解子系统的内部细节。

外观模式 VS 适配器模式

维度 外观模式 适配器模式
核心目的 简化复杂系统的调用(提供新接口) 解决接口不兼容问题(兼容已有接口)
设计意图 主动创建高层接口优化用户体验 被动适配已有接口满足调用方需求
结构特征 包含多个子系统的引用(聚合关系) 单个被适配对象的引用 (组合/继承关系)
对下层的关系 协调多个子系统(一对多) 适配一个对象(一对一)

注意事项

  1. 明确职责边界,外观类仅负责简化调用,不增加业务逻辑。
  2. 子系统间相互独立,允许子系统独立演化,避免子系统间相互耦合依赖,牵一发而动全身。

你可能感兴趣的:(外观模式,python,设计模式)