《外观模式》|设计模式系列第11篇
系列:结构型模式 · 外观模式(Facade Pattern)
关键词:门面、统一入口、简化调用、封装子系统、降低耦合
一、什么是外观模式
外观模式(Facade Pattern):为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

属于结构型设计模式。
简单理解:
外观就像酒店前台。酒店内部包含保洁、维修、餐饮等多个独立部门(子系统),客人不需要分别去找各个部门沟通;只需要找前台(外观),前台内部去协调各个子系统。外观不修改子系统原有代码,只是封装复杂调用流程,对外暴露简单入口。
核心意图
封装多个子系统的复杂调用逻辑,对外提供简洁统一高层接口,降低客户端使用复杂度。
适用场景
- 复杂子系统,客户端需要多次调用多个类才能完成业务
- 希望隔离客户端与子系统,减少依赖
- 分层架构,每一层对外提供 Facade,层与层之间通过外观通信
- 新旧系统整合,提供统一接入入口
⚠️ 缺点预警:外观类职责过重;外观类修改会影响全部客户端;不要过度包装。
二、UML结构图
角色划分:
- Facade(外观):高层接口,内部调用多个子系统模块,封装调用流程
- SubSystem(子系统):多个独立模块,实现底层能力,不知道 Facade 的存在
- Client(客户端):只依赖 Facade,不直接访问子系统

三、Java 完整示例
场景:影院家庭影院系统,包含 Light、Projector、Player。观影需要依次执行开灯、开投影、开播放器;观影结束依次关闭设备。
代码全部使用英文。
1. SubSystem 子系统
// Light
public class Light {
public void dim() {
System.out.println("Light dim to low brightness");
}
public void bright() {
System.out.println("Light turn to bright");
}
}
// Projector
public class Projector {
public void on() {
System.out.println("Projector turn on");
}
public void off() {
System.out.println("Projector turn off");
}
}
// Player
public class Player {
public void play() {
System.out.println("Media player start playing");
}
public void stop() {
System.out.println("Media player stop");
}
}
2. Facade 外观类
public class HomeTheaterFacade {
private Light light;
private Projector projector;
private Player player;
public HomeTheaterFacade(Light light, Projector projector, Player player) {
this.light = light;
this.projector = projector;
this.player = player;
}
public void watchMovie() {
System.out.println("=== Prepare to watch movie ===");
light.dim();
projector.on();
player.play();
}
public void endMovie() {
System.out.println("=== End movie ===");
player.stop();
projector.off();
light.bright();
}
}
3. Client 客户端
public class Client {
public static void main(String[] args) {
Light light = new Light();
Projector projector = new Projector();
Player player = new Player();
HomeTheaterFacade theater = new HomeTheaterFacade(light, projector, player);
theater.watchMovie();
theater.endMovie();
}
}
客户端只需要调用 watchMovie() 和 endMovie(),不需要关心内部多个设备调用顺序。子系统类保持不变,依然可以被其他代码单独调用。
四、外观模式 vs 适配器模式
| 模式 | 目标 | 核心 |
|---|---|---|
| Facade | 简化多个子系统调用,提供新的高层接口 | 整合多个子系统,简化使用 |
| Adapter | 转换已有接口,兼容已有类 | 包装单个对象,转换接口 |
五、优缺点总结
✅ 优点
- 简化客户端调用,减少客户端依赖
- 解耦客户端与子系统,子系统内部修改不影响上层客户端
- 更好的分层管控,提供统一访问入口
❌ 缺点
- 外观类容易职责膨胀,违背单一职责
- 新增子系统时,可能需要修改外观类,违反开闭原则
- 如果设计不当,容易变成万能类
六、框架源码应用
- Spring
JdbcTemplate:封装JDBC底层 Connection、Statement、ResultSet 等一系列子系统操作 - Tomcat RequestFacade
- MyBatis SqlSession 作为门面,封装底层Executor、StatementHandler等组件
七、小结
外观模式核心:为一组子系统提供高层统一入口,简化客户端调用,不改变子系统原有接口。
外观只是简化调用,不会限制客户端直接访问底层子系统。分层架构中非常常用。
0 条笔记