什么是外观模式

外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

外观模式的定义相对来说没那么好理解,但是外观模式本质上是一种非常简单的设计模式,我在这里为大家解释一下相信大家就能够明白。

举例说明

我们先看下面这张图

在这里插入图片描述

我们先来看左边, 在左边下方的大方框之后的就是我们的系统,大方框之外的是我们的调用类,上面的线就是上面的线就是系统中的各个模块与调用者之间的关系,这样来看是不是特别的乱。各个系统各个模块之间互相调用,那么对于调用者来说就需要了解每个系统模块之间存在什么关系,各自有什么作用,都了解清楚了之后,调用者才能够使用它们。

然后我们来看右边,右边我们在大方框中增加了一个Facade类,也就是使用了外观模式,在使用了外观模式之后,大方框外部的客户类全部都通过调用Facade类来调动系统功能,而不需要知道系统本身的各个模块是如何关联的。也就是说系统内部的实现被封装了起来,对于外部的调用则通过了一个通用的类,也就是外观类Facade来实现。对于调用方来说,他们就只需要调用Facade来实现对应的需求就可以,而对于系统内部是如何实现的,则不需要关心。

就像上面这样,为一组功能(类)提供了一个一致的外观类(界面),使得这组功能更容易被调用的方式就是外观模式。

这样大家明白了什么是外观模式之后,我们就通过一个具体的例子来看一下,外观模式在实际前端开发中的应用。

外观模式在前端中一个比较常见的应用方式就是,同法不同参 的使用方式 , 什么是 同法不同参 呢? 我们先来看下面的这段代码。

1
2
3
4
5
6
7
8
function bindEvent (element, type, selector, fn) {
if (fn == null) {
fn = selector;
selector = null;
}

fn();
}

看上面的代码,我们首先定义了一个方法bindEvent,它默认有四个参数element, type, selector, fn, 但是除了默认的四个参数之外,它又存在一种3个参数的调用方式,当我们在调用bindEvent的时候只传递3个参数,也就是没有fn的情况下,bindEvent就会把selector的内容赋值给fn,同时把selector置为null

这样我们就可以按照下面的方式进行调用。

1
2
3
4
5
6
7
8
9
var element;

bindEvent(element, 'click', '#div1', function () {
console.log('#div1 onClick');
});

bindEvent(element, 'click', function () {
console.log('onClick');
});

这种 同法不同参 的函数定义在前端的代码中是非常常见的。

使用场景

明白了上面的内容之后,我们来看外观模式的使用场景,对于外观模式的一个经典使用,就是在jQuery的事件绑定之后。

我们以绑定点击事件为例,在现如今的浏览器的环境中,不同的浏览器厂家,不同版本的浏览器,他们对js方法的解释方式会存在很多的差异,比如说,当我们想要为一个元素去绑定点击事件,我们可以通过:

1
dom.addEventListener(type,fn,false);

通过addEventListener方法来去实现,但是对于addEventListener来说,在某些浏览器上比如IE8就并不支持。面对这样的一种问题,我们可能首先想到的就是通过jQuery去进行事件绑定,借助jQuery所提供的on方法来去为某个元素去绑定一个点击事件,那么代码应该如下:

1
2
3
element.on('click', functyion () {
...
})

我们以这种方法进行的事件绑定,可以在包括IE8在内的所有浏览器中全部生效。那么针对on方法,jQuery是如何去实现的呢?我们来看下面这一段代码:

1
2
3
4
5
6
7
8
9
10
11
function on(dom, type, fn){
// 对于支持dom2级事件处理程序 addEventListener 方法的浏览器
if(dom.addEventListener){
dom.addEventListener(type,fn,false);
}else if(dom.attachEvent){
// 对于不支持addEventListener 方法但支持attachEvent 方法的浏览器
dom.attachEvent('on'+type,fn);
}else {
dom['on'+ type] = fn;
}
}

这一段代码就是jQuery on方法的一个简单逻辑实现,他的第一个参数dom,是为了方便我们在这里演示而加上去的,我们正式在使用jQuery on的时候并不需要上传dom参数。

在上面的方法中,它进行了三次的逻辑判断,首先判断浏览器是否支持addEventListener方法,如果不支持的话,就改用attachEvent,如果上面两种方法都不支持的话,那么就采用dom['on'+ type] = fn;的方式。jQuery通过on方法来把上面的逻辑进行封装,然后展示给我们的是一个统一个调用方式,以此来达到方便我们调用的目的。这样的一种方式就是外观模式的体现。

总结

本章我们介绍的是外观模式,外观模式的核心就是 对复杂逻辑进行封装,对外提供一个高级的方法Facade来让开发者使用。 在大家面临着一个有用复杂逻辑,或者是一个复杂模块需要被封装的时候,就可以考虑使用外观模式