前言

隐藏系统的复杂性,并向客户端提供一个客户端可以访问系统的接口,通过这个接口使得对子系统接口的访问更加容易,提供对客户端系统的简化方法和现有系统类方法的委托调用。
其实也是属于面向对象编程中的一种编程思维模式:针对接口编程,在面对不同的复杂对象,仅需要将复杂对象对外提供统一的简单明确调用的业务方法,然后自身隐藏复杂逻辑其中,调用者无须关心内部具体实现业务逻辑

意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。

何时使用: 1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个”接待员”即可。 2、定义系统的入口。

如何解决:客户端不与系统耦合,外观类与系统耦合。

关键代码:在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。

ES5代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 var A = {
g: function(id) {
return document.getElementById(id);
},
css: function(id, key, value) {
document.getElementById(id).style[key] = value;
},
attr: function(id, key, value) {
document.getElementById(id)[key] = value;
},
html: function(id, html) {
document.getElementById(id).innerHTML = html;
},
on: function (id, type, fn){
document.getElementById(id)['on' + type] = fn;
}
};

这里将所有的对元素的操作api,都集成在A对象中,所有需要针对dom元素进行操作的调用,仅需要通过A.css('box', 'background', 'red');即可

🤔 这里发现有可优化的空间,比如模仿jQuery的一个链式调用,部分方法无须重新编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 var A = {
g: function(id) {
return document.getElementById(id);
},
css: function(id, key, value) {
this.g(id).style[key] = value;
return this;
},
attr: function(id, key, value) {
g(id)[key] = value;
return this;
},
html: function(id, html) {
g(id).innerHTML = html;
return this;
},
on: function (id, type, fn){
g(id)['on' + type] = fn;
return this;
}
};

针对⬆️的调整,我们可以是直接通过以下的方式来直接调用:

A.css(‘box’, ‘background’, ‘red’).attr(‘box’, ‘alt’, ‘test content’);

优化后的ES6代码

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
// A.js
export default class {
static _instance = null;
constructor(props) {
super(props);
}
static getInstance(){
if(!_instance){
_instance = new A();
}
return _instance;
}
css(id, key, value) {
this.g(id).style[key] = value;
return this;
}
attr(id, key, value) {
g(id)[key] = value;
return this;
}
html(id, html) {
g(id).innerHTML = html;
return this;
}
on (id, type, fn){
g(id)['on' + type] = fn;
return this;
}
}

这里结合之前所习得的单例模式,对外仅暴露统一的一个API对象来对当前复杂系统进行调用