这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战
外观模式
结构型设计模式,通过引入外观角色来解耦客户端和子系统的之间的交互,为复杂的子系统调用提供一个统一的入口。
模式结构
- 外观角色 Facade :提供一个外观接口,主要是提供给客户端的,其内是对接多个子系统,然后统一接口提供给客户端
- 子系统角色 SubSystem:多个子系统或者是模块都有各自独立的功能。各子系统都是独立不会意识到外观的存在,它们在系统内运作并且相互之间可直接进行交互
- 客户角色:通过外观角色访问各个子系统的功能
TypeScript示例代码:
// 外观类
class Facade {
private sub1: SubSystem1;
private sub2: SubSystem2;
constructor(sub1: SubSystem1 = null, sub2: SubSystem2 = null) {
this.sub1 = sub1 || new SubSystem1();
this.sub2 = sub2 || new SubSystem2();
}
doDeal() {
this.sub1.doDeal();
this.sub2.doDeal();
}
}
// 子系统1
class SubSystem1 {
doDeal() {
console.log("subsystem1 run");
}
}
// 子系统2
class SubSystem2 {
doDeal() {
console.log("subsystem2 run");
}
}
(() => {
// 我是客户端
const facade = new Facade();
facade.doDeal();
})();
主要优点
- 降低客户端类和子系统类的耦合,子系统变化而不影响客户端
- 子系统类各自独立完成功能
主要缺点
- 外观角色类可能会变成所有客户端类与子系统连结的中间类,所有都依赖外观角色类,角色类就会变得设计过重
适用场景
- 随着功能迭代,子系统越来越复杂,越来越多,且实现的功能比较多时,此时可以使用外观模式,为客户端提供一个直接访问子系统的接口
- 多个子系统可以划分多个层次结构时,然后使用外观模式定义子系统的各层次的入口,然后通过外观模式进行交互,减少子系统之间的耦合
- 使用外观模式可以分离客户端和子系统之间的的联系,提供子系统的独立性和移植性
所以,当某功能关联多个子系统的时候,外观模式很适合。比如直播平台需要生成视频时,需要处理音频和视频,然后再合成视频,此时可以划分成音频和视频2个子模块,再使用外观类提供给客户端调用。