Java编程之外观模式
前言
想象你要去一家很复杂的餐厅吃饭,但不想自己点菜、排队、找位置,也不想管厨房、洗碗、送餐这些后端流程。你只需要告诉餐厅服务员“我要一份牛排套餐”,然后坐等就好。这个服务员,就是外观模式(Facade Pattern)
模式定义
外观模式(Facade Pattern)是一种结构型设计模式,其核心目标是为复杂子系统提供一个统一的高层接口,简化客户端与系统的交互。它通过封装子系统的复杂逻辑,隐藏底层细节,使客户端无需了解子系统内部实现即可完成操作。这种模式符合迪米特法则(最少知识原则),有效降低了系统耦合度。
核心思路
外观模式就是给一大堆复杂系统(子系统)加一个“门面”/“服务员”:
- 客户端只跟这个门面打交道,只需一句话完成任务;
- 门面负责协调各个子系统(菜品准备、厨房、收银、送餐等)完成请求;
- 客户端无需知道内部复杂流程,只关注结果。
┌─────────┐│ Client ││─────────││meal() │└─────────┘││ calls▼┌───────────────────────┐│ RestaurantFacade │ ◀───┐│──────────────────────│ │ 门面角色,隐藏内部流程│ + orderMeal(): void │ │└───────────────────────┘ ││ │ │ ││ │ │ coordinates│ │ ▼│ │ ┌───────────────┐│ │ │ Kitchen │ 子系统 A:做菜│ │ │ + cookFood() ││ │ └───────────────┘│ ▼│ ┌───────────────┐│ │ Cashier │ 子系统 B:收银│ │ + takePayment()││ └───────────────┘▼┌───────────────┐│ WaiterDelivery│ 子系统 C:送餐│ + deliver() │└───────────────┘
就像你打电话叫外卖,不用自己跑去不同店铺、找骑手、付钱、还要问“什么时候送到”……
你只需要叫一个号码(比如美团/饿了么),对方帮你搞定全部流程。
代码示例
以家庭智能控制为例子来说明,灯光,空调,音响智能设备的开启为例子如下:
// 子系统 A
//灯光
class Light { void on() { System.out.println("Lights ON"); }
}
//空调
class AC{ void setTemp(int t) { System.out.println("AC set to " + t); }
}
//音响
class Music { void play() { System.out.println("Music playing"); }
}// 外观类
class SmartHomeFacade {private Light light = new Light();private AC ac = new AC();private Music music = new Music();public void startEvening() {light.on();ac.setTemp(22);music.play();}
}// 客户端
SmartHomeFacade home = new SmartHomeFacade();
home.startEvening();
// 输出:Lights ON
// AC set to 22
// Music playing
客户端不用管 Light、AC、Music 怎么协作,只调用 startEvening()
一句话搞定所有流程。
特点总结
优点 | 解释 |
---|---|
1. 使用简单 | 客户只关注一两个调用,不需要学习复杂系统 |
2. 隐藏内部细节 | 子系统内部发生什么,客户端完全不关心 |
3. 解耦 | 子系统可以独立变化,不影响客户端 |
4. 有统一入口 | 便于控制、安全、维护 |
使用场景
- 当系统复杂,涉及多个子模块,但客户端只需一部分功能;
- 当你想隔离外部代码对内部的依赖,便于将来变动时更灵活;
- 当你想给外部提供简易、安全、统一的入口。
小结
外观模式就是帮助你写一个“智能接待员”——让系统对外更友好,同时把复杂逻辑藏在后台。就像用遥控器控制电视,不用自己打线路、管芯片。业务简单了,代码也更清晰、更易扩展。是不是很简单,你看懂了么?
参考
《23种设计模式概览》