外观模式(Facade Pattern)
·
外观模式(Facade Pattern) 是一种结构型设计模式,其核心思想是 为复杂的子系统提供一个统一的高层接口,简化客户端与子系统的交互,同时降低系统的耦合度。
核心思想
- 隐藏复杂性:将多个子系统复杂的调用过程封装成一个简单的接口,客户端只需与这个接口交互,无需关心背后的实现细节。
- 统一入口:为子系统定义一个“窗口”,所有功能通过这个窗口调用,避免客户端直接操作多个子系统。
结构(UML 类图)
┌───────────────────┐ ┌───────────────────┐
│ Facade │<>------>│ SubsystemA │
├───────────────────┤ ├───────────────────┤
│ +simpleMethod() │ │ +methodA() │
└───────────────────┘ └───────────────────┘
▲
│
│
┌───────────────────┐
│ SubsystemB │
├───────────────────┤
│ +methodB() │
└───────────────────┘
- Facade(外观类):提供简化接口,内部调用多个子系统的方法。
- Subsystem(子系统类):实现具体功能,但对外部透明。
- Client(客户端):只与
Facade交互,不直接依赖子系统。
举个实际例子
场景:家庭影院系统包含电视、音响、灯光等多个设备,开启“观影模式”需要按顺序执行:
- 关闭灯光
- 打开电视
- 打开音响
- 调节音量
未用外观模式:
用户需要手动依次调用每个设备的方法:
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(); // 只需一行代码!
适用场景
- 简化复杂系统:当系统有多个子系统,且交互逻辑复杂时。
- 分层设计:为不同层次的代码提供统一接口(例如 API 网关)。
- 遗留系统封装:为老旧的代码提供新接口,避免直接修改旧代码。
优点
- 降低耦合:客户端只依赖外观类,不直接与子系统交互。
- 简化使用:客户端代码更简洁,无需了解子系统细节。
- 灵活性:修改子系统内部逻辑时,只需调整外观类,不影响客户端。
缺点
- 过度封装风险:如果外观类设计不当,可能掩盖子系统的灵活性。
- 单点依赖:外观类可能成为系统的“上帝对象”,承担过多职责。
与其他模式对比
- 适配器模式:适配器解决接口不兼容问题,而外观模式解决接口复杂性问题。
- 中介者模式:中介者协调对象间的交互,外观模式协调子系统的对外接口。
- 单例模式:外观类通常设计为单例(但非必须)。
总结
外观模式通过 封装复杂性 和 提供统一入口,让代码更简洁、易维护。它是重构复杂代码、简化系统交互的利器,尤其适合大型系统或需要分层设计的场景。
更多推荐



所有评论(0)