外观模式(Facade Pattern) 是一种结构型设计模式,其核心思想是 为复杂的子系统提供一个统一的高层接口,简化客户端与子系统的交互,同时降低系统的耦合度。


核心思想

  • 隐藏复杂性:将多个子系统复杂的调用过程封装成一个简单的接口,客户端只需与这个接口交互,无需关心背后的实现细节。
  • 统一入口:为子系统定义一个“窗口”,所有功能通过这个窗口调用,避免客户端直接操作多个子系统。

结构(UML 类图)

┌───────────────────┐          ┌───────────────────┐
│      Facade       │<>------>│   SubsystemA      │
├───────────────────┤          ├───────────────────┤
│ +simpleMethod()   │          │ +methodA()        │
└───────────────────┘          └───────────────────┘
                                    ▲
                                    │
                                    │
                       ┌───────────────────┐
                       │   SubsystemB      │
                       ├───────────────────┤
                       │ +methodB()        │
                       └───────────────────┘
  • Facade(外观类):提供简化接口,内部调用多个子系统的方法。
  • Subsystem(子系统类):实现具体功能,但对外部透明。
  • Client(客户端):只与 Facade 交互,不直接依赖子系统。

举个实际例子

场景:家庭影院系统包含电视、音响、灯光等多个设备,开启“观影模式”需要按顺序执行:

  1. 关闭灯光
  2. 打开电视
  3. 打开音响
  4. 调节音量

未用外观模式
用户需要手动依次调用每个设备的方法:

lights.off();
tv.on();
speaker.on();
speaker.setVolume(50);

使用外观模式
定义一个 HomeTheaterFacade 类,封装上述步骤:

public class HomeTheaterFacade {
    private Lights lights;
    private TV tv;
    private Speaker speaker;

    public HomeTheaterFacade() {
        lights = new Lights();
        tv = new TV();
        speaker = new Speaker();
    }

    // 统一入口:一键开启观影模式
    public void watchMovie() {
        lights.off();
        tv.on();
        speaker.on();
        speaker.setVolume(50);
    }
}

// 客户端调用
HomeTheaterFacade facade = new HomeTheaterFacade();
facade.watchMovie(); // 只需一行代码!

适用场景

  1. 简化复杂系统:当系统有多个子系统,且交互逻辑复杂时。
  2. 分层设计:为不同层次的代码提供统一接口(例如 API 网关)。
  3. 遗留系统封装:为老旧的代码提供新接口,避免直接修改旧代码。

优点

  1. 降低耦合:客户端只依赖外观类,不直接与子系统交互。
  2. 简化使用:客户端代码更简洁,无需了解子系统细节。
  3. 灵活性:修改子系统内部逻辑时,只需调整外观类,不影响客户端。

缺点

  1. 过度封装风险:如果外观类设计不当,可能掩盖子系统的灵活性。
  2. 单点依赖:外观类可能成为系统的“上帝对象”,承担过多职责。

与其他模式对比

  • 适配器模式:适配器解决接口不兼容问题,而外观模式解决接口复杂性问题。
  • 中介者模式:中介者协调对象间的交互,外观模式协调子系统的对外接口。
  • 单例模式:外观类通常设计为单例(但非必须)。

总结

外观模式通过 封装复杂性提供统一入口,让代码更简洁、易维护。它是重构复杂代码、简化系统交互的利器,尤其适合大型系统或需要分层设计的场景。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐