每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题解决方案的核心。这样,你就能一次又一次的使用该方案而不必要做重复劳动。

一般而言,一个模式有四个基本要素:

1.模式名称

2.问题

3.解决方案

4.效果

订阅发布者模式(vue事件)

策略模式

定义一系列的算法,把他们封装起来,并且使他们可以相互替换

策略模式的目的是将算法的使用和算法的实现分离开来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var strategies = {
"s": function (salary) {
return salary * 4
},
"A": function (salary) {
return salary * 3
},
"B": function (salary) {
return salary * 2
}
}

var calculateBonus = function (level, salary) {
return strategies[level](salary)
}

单例模式(全局弹窗)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 实现单例模式的思路

用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 单例模式
var Singleton = function (name) {
this.name = name
}
Singleton.prototype.getName = function () {
alert(this.name)
}
Singleton.getInstance = (function () {
var instance = null
return function( name ){
if ( !instance ){
instance = new Singleton( name )
}
return instance
}
})()

var a = Singleton.getInstance( 'sven1' );
var b = Singleton.getInstance( 'sven2' );
alert ( a === b ); // true

代理模式

中介者模式

通过中介者对象,其他所有的相关对象都通过该中介者对象来通信,而不是相互引用,当其中的一个对象发生改变时,只需要通知中介对象即可。通过中介者模式可以接触对象与对象之间的紧耦合关系。

中介者模式的实际业务场景

  • 购物车需求
    商品选择、颜色选择、购买数量等等都会触发订单change,那么可以通过中介者来转发处理这些事件,实现各个事件的解耦,仅仅维护中介者对象即可。

redux、vuex都属于中介者模式的实际应用,我们把共享的数据,抽离成一个单独的store,每个都通过store这个中介来操作对象。

装饰器模式

在不改变对象自身的基础上,在程序运行期间给对象动态的添加方法。

常见应用,react的高阶组件,或者react-redux中的@connect或者自己定义一些高阶组件

  • 比如页面中有一个button,点击button会打开一个弹窗,同时会上报埋点数据用于统计button的点击次数。
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
// 常规写法

function showDialog () {
console.log('打开弹窗')
log(this.getAttribute('tag'))
}

function log (tag) {
console.log('上报埋点数据' + tag)
}

document.getElementById('button').onclick= showDialog

// 装饰器写法

// 先实现一个after
Function.prototype.after = function (afterfun) {
var __self = this
return function () {
var ret = __self.apply(this, arguments)
afterfun.apply(this, arguments)
return ret
}
}
function showDialog () {
console.log('打开弹窗')
}

function log () {
console.log('上报埋点数据' + this.getAttribute('tag'))
}

showDialog = showDialog.after(log) // 打开弹窗后上报数据

document.getElementById('button').onclick= showDialog

vue中的v-input v-checkbox 也可以认为是一种装饰器模式,对原生的input和checkbox做一层装饰

外观模式

外观模式即让多个方法一起被调用

涉及到兼容性、参数支持多格式,对外只暴露一个函数,内部判断实现

工厂模式

提供创建对象的接口,把成员对象的创建工作交给一个外部对象,好处在于消除对象之间的耦合(也就是相互影响)

常见例子: 弹窗、message、对外提供的api,都是调用api,然后新建一个弹窗或者message的实例,这些都是典型的工厂模式

设计模式不能滥用