设计模式之中介者模式(Mediator)

介绍

中介者模式的作用就是解除对象与对象之间的紧耦合关系。增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。中介者使各对象之间耦合松散,而且可以独立地改变它们之间的交互。中介者模式使网状的多对多关系变成了相对简单的一对多关系.

设计模式之职责链模式(Chain of responsibility)

定义

职责链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间 5 的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

职责链模式的名字非常形象,一系列可能会处理请求的对象被连接成一条链,请求在这些对 象之间依次传递,直到遇到一个可以处理它的对象,我们把这些对象称为链中的节点。

call()、apply()、bind()的用法

在javascript中,函数不仅是一种语法,也是值,也就是说,可以将函数赋值给变量,存储在对象的属性或数组的元素中, 作为参数传入另外一个函数等。

bind、call、apply

每一个函数都包含一个 prototype属性,这个属性是指向一个对象的引用,这个对象称作“原型对象”。 每一个函数都包含不同的原型对象。当将函数用作构造函数的时候,新创建的对象会从原型对象上继承属性。

Function.prototype.call()

call() 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法.

注意:该方法的作用和 apply() 方法类似,只有一个区别,就是call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。

1
2
3
fun.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg[, argsArray])

设计模式之享元模式(Flyweight)

介绍

享元(flyweight)模式是一种用于性能优化的模式,享元模式的核心是运用共享技术来有效支持大量细粒度的对象。

享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生产大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数以外,开销基本相同的话,就可以大幅度较少需要实例化的类的数量。如果能把那些参数移动到类实例的外面,在方法调用的时候将他们传递进来,就可以通过共享大幅度第减少单个实例的数目。

那么如果在JavaScript中应用享元模式呢?有两种方式:

  • 第一种是应用在数据层上,主要是应用在内存里大量相似的对象上;
  • 第二种是应用在DOM层上,享元可以用在中央事件管理器上用来避免给父容器里的每个子元素都附加事件句柄

设计模式之模板模式(TemplateMethod)

在 JavaScript 开发中用到继承的场景其实并不是很多,很多时候我们都喜欢用 mix-in 的方式给对象扩展属性。但这不代表继承在 JavaScript 里没有用武之地,虽然没有真正的类和继承机制,但我们可以通过原型 prototype 来变相地实现继承。

定义

模板方法模式是一种只需使用继承就可以实现的非常简单的模式。

模板方法模式由两部分结构组成:

  • 第一部分是抽象父类,
  • 第二部分是具体的实现子类。

通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。

设计模式之发布/订阅模式(Publish/Subscribe)

发布/订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript 开发中,我们一般用事件模型来替代传统的发布/订阅模式

遍地的发布订阅现象

如今的信息化时代,发布/订阅模式的应用可以说非常广泛,比如微信公众号就是典型的发布/订阅模式,公众号发布一条信息,所有的订阅者都会收到。

有人可能也会想到经常收到的各种广告短信信息(有的可能是被动订阅),其实发送短信通知或广告也是一个典型的发布/订阅模式。

发布/订阅模式可以广泛用于异步编程中,代替传递回掉函数的方案,比如,我们可以订阅 ajax 请求的 error、succ 等事件。

另外发表订阅让两个对象松耦合在一起,不必了解彼此细节,当有新的订阅者出现时,发布者的代码不需要任何修改。同样发布者需要改变时,也不会影响到之前的订阅者。只要之前约定的事件名没有变化,就可以自由地改变它们。

设计模式之策略模式(Strategy)

在程序设计中,我们也常常遇到这样的情况,要实现某一个功能有多种方案可以选择。比如一个压缩文件的程序,既可以选择 zip 算法,也可以选择 gzip 算法。
这些算法灵活多样,而且可以随意互相替换。这种解决方案就是将要介绍的策略模式。

定义

策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

从定义上看,策略模式就是用来封装算法的。但如果把策略模式仅仅用来封装算法,未免有一点大材小用。在实际开发中,我们通常会把算法的含义扩散开来,使策略模式也可以用来封装一系列的“业务规则”。只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以用策略模式来封装它们。

设计模式之迭代器模式(Iterator)

迭代器模式是一种相对简单的模式,简单到很多时候我们都不认为它是一种设计模式。目前的绝大部分语言都内置了迭代器。

比如:JavaScript 的 Array.prototype.forEach

jQuery里一个非常有名的迭代器就是 $.each 方法,通过each我们可以传入额外的function,然后来对所有的item项进行迭代操作,例如:

1
2
3
4
5
6
7
$.each( [1, 2, 3], function( i, n ){
console.log( '当前下标为: '+ i,'当前值为:' + n );
});
// 下标: 0 当前值:1
// 下标: 1 当前值:2
// 下标: 2 当前值:3

设计模式之代理模式(Proxy)

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。

定义

代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下:

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。