外观模式¶
分类:结构型模式。
类结构¶
classDiagram
direction TB
class Client
class Facade {
+operation()
}
class SubsystemA {
+operationA()
}
class SubsystemB {
+operationB()
}
Client ..> Facade : 使用
Facade --> SubsystemA : 委托
Facade --> SubsystemB : 委托
角色定义¶
| 角色 | 定义 |
|---|---|
| Client(客户端) | 通过门面完成常用任务,减少对多个子系统接口的直接依赖。 |
| Facade(门面) | 提供统一的高层入口,持有并协调子系统对象,将请求委托给相应子系统。 |
| SubsystemA(子系统 A) | 实现一部分实际业务功能,接受门面的委托,无需感知门面。 |
| SubsystemB(子系统 B) | 实现另一部分实际业务功能,与其他子系统协作完成门面组织的任务,无需感知门面。 |
Head First 示例:一键开始家庭影院观影¶
《Head First 设计模式》第 7 章的家庭影院包含功放、播放器、投影机、屏幕、灯光和爆米花机。开始观影需要按顺序操作多台设备,结束时又要逐项恢复。作者 2020 年第二版配套代码 facade/hometheater 用 HomeTheaterFacade.watchMovie() 与 endMovie() 封装这两组操作;本版本的播放设备具体类名是 StreamingPlayer。
外观对象通过构造器接收设备引用,由它组织常用流程。各设备仍保留自己的方法,也不需要依赖外观。示例入口负责创建和连接设备,观影时则只需调用外观的两个高层方法。
| 具体类名 | 对应角色 | 职责 |
|---|---|---|
HomeTheaterFacade |
外观 | 持有设备引用,按顺序执行观影准备和结束操作。 |
Amplifier |
功放子系统 | 选择播放器,设置环绕声和音量,控制功放开关。 |
StreamingPlayer |
播放子系统 | 保存影片信息,提供开关机、播放和停止方法。 |
Projector |
投影子系统 | 持有播放器引用,提供开关机和宽屏设置。 |
Screen |
屏幕子系统 | 通过 down() 和 up() 放下或收起屏幕。 |
TheaterLights |
灯光子系统 | 通过 dim() 调暗灯光,通过 on() 恢复照明。 |
PopcornPopper |
爆米花子系统 | 提供开关和制作爆米花的方法。 |
HomeTheaterTestDrive |
客户端与组装入口 | 创建设备和外观,调用 watchMovie()、endMovie()。 |
示例 UML¶
classDiagram
direction TB
class HomeTheaterFacade {
+watchMovie(String movie)
+endMovie()
}
class Amplifier {
+on()
+off()
+setStreamingPlayer(StreamingPlayer player)
+setSurroundSound()
+setVolume(int level)
}
class StreamingPlayer {
+on()
+off()
+play(String movie)
+stop()
}
class Projector {
+on()
+off()
+wideScreenMode()
}
class Screen {
+down()
+up()
}
class TheaterLights {
+dim(int level)
+on()
}
class PopcornPopper {
+on()
+pop()
+off()
}
class HomeTheaterTestDrive {
+main(String[] args)$
}
HomeTheaterTestDrive ..> HomeTheaterFacade : 组装并调用
HomeTheaterFacade --> Amplifier : amp
HomeTheaterFacade --> StreamingPlayer : player
HomeTheaterFacade --> Projector : projector
HomeTheaterFacade --> Screen : screen
HomeTheaterFacade --> TheaterLights : lights
HomeTheaterFacade --> PopcornPopper : popper
Amplifier --> StreamingPlayer : player
StreamingPlayer --> Amplifier : amplifier
Projector --> StreamingPlayer : player
图中只保留观影流程,省略收音机 Tuner、未参与这段流程的 CdPlayer,以及设备描述、构造器和其他播放功能。关联线上的名称来自实际字段;这些设备类都是普通具体类,没有额外的子系统接口或共同父类。
协作过程¶
HomeTheaterTestDrive创建各设备,将播放器传入投影机构造器,并把观影所需对象传给HomeTheaterFacade。- 调用
watchMovie(String movie)后,外观先开启爆米花机并制作爆米花,再把灯光调到10、放下屏幕、开启投影机并设置宽屏。 - 外观开启功放,调用
setStreamingPlayer(player)选择播放来源,开启环绕声并将音量设为5,最后开启播放器并调用play(movie)。 - 调用
endMovie()后,外观依次关闭爆米花机、恢复灯光、收起屏幕、关闭投影机和功放,最后停止并关闭播放器。
固定版本源码:
- HomeTheaterFacade:观影流程的编排
- Amplifier:选择播放来源与设置声音
- StreamingPlayer:第二版的播放设备
- HomeTheaterTestDrive:设备组装与示例入口