外观模式简化了系统与用户的交互流程。提供统一接口访问系统和其下的子系统的所有接口。用户只需要与外观接口交互就能使用整个系统。
问题场景
高解耦系统(所有类的设计遵循「单一责任原则」,即每一个类只负责最小的功能)通常拥有相互组合但解耦的数量众多的类。初始化某个系统可能涉及到较繁杂的实例化流程(因为类 A 可能需要类 B 的实例用于初始化,而类 B 又需要类 C 的实例初始化)。
复杂的实例化流程不代表高解耦系统是不好的,这只是高解耦特性必然会带来的结果。
外观模式是什么?我们创造出一个虚拟的壳(外观),把系统的所有类全部包裹其中。使用系统的用户只需要与这个壳交互。
用现实的例子来比喻,汽车的一键启动按钮和全自动洗衣机的智能启动按钮。
驾驶者不需要了解汽车的内部构造,只需要学会点火、操纵方向盘和操纵杆以及控制油门和刹车,就能正常驾驶了。点火按钮、方向盘、操纵杆、油门和刹车都是汽车系统提供给驾驶者的接口。
全自动洗衣机只需要你 1)放入衣物;2)放入洗涤剂;3)按下启动按钮。它自动包揽设置水量、加水、洗涤、漂洗和脱水等洗衣程序。智能启动按钮就是洗衣机提供给操作者的接口。
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Computer { // 电脑内部系统
getElectricShock() {
console.log('Ouch!');
}
makeSound() {
console.log('Beep beep!');
}
showLoadingScreen() {
console.log('Loading...');
}
closeEverything() {
console.log('Closing everything...');
}
sooth() {
console.log('Zzzzz');
}
pullCurrent() {
console.log('Haaah!');
}
}
class ComputerFacade { // 电脑外观,提供开关
constructor(computer) {
this.computer = computer;
}
turnOn() {
this.computer.getElectricShock();
this.computer.makeSound();
this.computer.showLoadingScreen();
this.computer.pullCurrent();
console.log('Computer is on!');
}
turnOff() {
this.computer.sooth();
this.computer.closeEverything();
this.computer.pullCurrent();
console.log('Computer is off!');
}
}
const computer = new Computer();
const computerFacade = new ComputerFacade(computer);
computerFacade.turnOn();
computerFacade.turnOff();
输出:
1
2
3
4
5
6
7
8
9
10
Ouch!
Beep beep!
Loading...
Haaah!
Computer is on!
Zzzzz
Closing everything...
Haaah!
Computer is off!
得墨忒耳定律
A module should not know about the inner workings of the objects it manipulates.
只和你的密友谈话。
wiki: 得墨忒耳定律,又叫 The law of Demeter / Principle of least knowledge。
- 每個單元對於其他的單元只能擁有有限的知識:只是與當前單元緊密聯繫的單元;
- 每個單元只能和它的朋友交談:不能和陌生單元交談;
- 只和自己直接的朋友交談。
代码中表现为,减少连续调用链的长度:
1
2
3
a.b().c().d(); // No!
a.d(); // Yes! d() 中调用 b() 和 c()
对于任何对象,在该对象方法内都只调用以下范围内的方法:
- 对象本身
- 对象的任何组件
- 此方法所创建或实例化的任何对象
- 方法的输入参数中传入的任何对象
总而言之就是要减少耦合。
参考资料
- Youtube: facade pattern
- 《Head First 设计模式》第七章