在Unity开发中, 外观模式(Facade Pattern) 用于为复杂的子系统提供一个简化的统一接口, 让客户端(调用者)无需关心子系统的内部细节, 只需通过这个”外观”就能完成与子系统的交互, 从而降低客户端与子系统的耦合度.
举个具体场景: 角色出生流程
游戏中, 角色出生时需要触发一系列操作, 设计多个独立的子系统:
- 动画系统: 播放”出生动画”
- 音效系统: 播放”出生音效”
- UI 系统: 显示”欢迎提示”
- 状态系统: 初始化角色属性(生命值\攻击力等)
- 粒子系统: 播放”出生特效”
如果客户端(如
GameManager) 直接调用每个子系统的方法, 代码会非常繁琐(需要逐个获取子系统引用\调用初始化方法), 且一旦子系统内部修改(比如新增”摄像机聚焦”步骤), 客户端代码也需要跟着改.外观模式的解决思路是: 创建一个”角色出生外观类”, 内部封装所有子系统的交互逻辑, 客户端只需调用外观类的一个方法(如
SpawnCharacter() ) 即可完成所有操作.外观模式的核心角色
- 外观类(Facade): 封装子系统的交互逻辑, 提供统一的简化接口给客户端.
- 子系统类(Subsystem Classes): 多个独立的模块(如动画\音效系统), 各自实现具体功能, 不依赖外观类.
- 客户端(Client): 通过外观类与子系统交互, 无需直接调用子系统.
代码实现步骤
- 定义子系统类(独立功能模块)
先实现各个子系统, 每个子系统负责自己的功能(如动画\音效等), 它们彼此独立, 不依赖其它系统:
- 实现外观类(统一接口)
外观类持有所有子系统的引用, 封装角色出生的完整流程, 对外提供一个简化的
Spawn() 方法:3.客户端使用(简化交互)
客户端(如
GameManager ) 只需调用外观类的 Spawn() 方法, 无需关心内部子系统的细节:外观模式的核心优势
- 简化接口: 客户端无需记住多个子系统的接口, 只需调用外观类的一个方法(如
Spawn()), 大幅降低使用难度.
- 减低耦合: 客户端与子系统完全解耦(客户端知道外观类, 不知道子系统的存在). 如果子系统修改(比如音效系统换成新的 API), 只需修改外观类, 客户端代码无需变动.
- 隔离变化: 子系统的新增\删除或逻辑调整, 只需在外观类中同步修改, 不会影响客户端. 例如, 若要给出生流程新加一个”摄像机聚焦”步骤, 只需新增
CammeraSystem子系统, 并在外观类的Spawn()中调用其方法,GameManager无需任何修改.
外观模式 vs 适配器模式
- 外观模式: 简化接口, 为多个子系统提供统一入口(”化繁为简”).
- 适配器模式: 转换接口, 让不兼容的接口可以一起工作(”兼容旧接口”).
在 Unity 中的其他应用场景
- 场景加载: 加载场景时需要加载资源\初始化NPC\设置天气\播放背景音乐等, 用
ScenenLoadFacade统一处理
- 游戏暂停/继续: 暂停时需要暂停时间\显示暂停UI\停止音效\冻结角色\用
PauseFacade封装这些操作.
- 角色死亡: 死亡时需要播放死亡动画\音效\显示死亡 UI\触发复活倒计时, 用
CharacterDeathFacade统一调用.
总结: 外观模式就像 “前台服务员” ——— 你去酒店入住时, 只需告诉前台 “我要入住”, 前台会帮你协调客房\钥匙\早餐等所有环节, 你无需直接对接每个部门. 在Unity中, 它是简化复杂系统交互的”最佳拍档”.