JavaScript设计模式7——外观模式

128 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

前言

前几篇介绍的设计模式都一个特点,创建型设计模式。所谓创建型设计模式,就是通过某种方式控制对象的创建,来达到简化设计的复杂度与代码复杂度的目的。现在回想,不管是简单工厂模式,工厂方法模式,抽象工厂模式,还是建造者模式,原型模式,单例模式都是一类处理对象的设计模式。今天我们来点不一样的,结构性设计模式。它更关注于如何将类或者对象组合成更大更复杂的结构,简化设计。

今天我们先学习第一种结构性设计模式——外观模式。

先来看看菜鸟教程是怎样介绍外观模式的呢?

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。——菜鸟教程

看的懵懵的对吧。让我们来跳过这些玄而又玄的概念,直接看例子吧。

实例

开发中,给dom节点绑定事件是很平常的事。首先我们需要创建一个button。

<button id="btn">click me!</button>

接下来,我们需要给他绑定事件.浏览器运行点击,确实打印出来1,没问题。

const btn = document.getElementById('btn')
btn.onclick = function() {
    console.log(1);
}

这时候,同事接到了需求,需要点击按钮来触发某一些事件,同事比较懒,看到了button节点,没看到你写的点击事件。于是,他写了自己的点击事件。

btn.onclick = function() {
    console.log(2);
}

这时,bug出现了。他的点击事件覆盖了你的点击事件,原来依托你的点击事件触发的逻辑全部失效。功能丢失。那么应该怎么优化呢?我们需要封装一个添加事件的函数。

function addEvent(dom, type, fn) {
    // 支持addEventListener的浏览器
    if(dom.addEventListener) {
        dom.addEventListener(type, fn, false)
    }else if(dom.attachEvent) {
    // 支持attachEvent
        dom.attachEvent('on' + type, fn)
    }else{
    // 支持类似onclick事件的浏览器
        dom['on'+type] = fn
    }
}
addEvent(btn, 'click', function(){
    console.log(1);
})
addEvent(btn, 'click', function(){
    console.log(2);
})
addEvent(btn, 'click', function(){
    console.log(3);
})

封装完成,运行之后,事件也都添上了。很简单吧。让我们从例子中脱离出来。

我们需要明确的是,我们要绑定多个事件得使用事件监听函数。但是各大浏览器实现的方式不大一致。所以我们需要将这些不统一的接口封装起来,定义一个统一接口方法,提供了一个更简单的高级接口。而这就是对外观模式的应用。

总结

现在我们便能理解这段话了:外观模式隐藏系统的复杂性(对比例子,隐藏各个浏览器中同样功能的不同方法),并向客户端提供了一个客户端可以访问系统的接口(提供一个更简单的高级接口)。