观察者模式,是Gof4在经典书籍《设计模式--可复用面向对象软件的基础》提出的一种设计模式。
何为观察者模式呢?

让我们举个

就一目了然了。

大家应该都有去过银行取款的经历,刚进银行,会有热情的客服MM迎上来让你取号。
取号的过程,就可以理解为加入了某个观察团,对被观察者(柜台)进行观察。
试想,如果没有这个过程,我们会怎么做呢?没错,就是不断的去柜台进行询问和催促:轮到我了没?柜台的GGMM每天要接待上百个业务,被你不断的骚扰说不定会有拿出砍刀的冲动。
被观察者的状态会不断发生变化,变化的时候会通过广播的方式来告知大家。
这样就构成了一个简单的观察者模式。

也许你已经有了大概的了解,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。
而不是需要观察者不断的去询问被观察者是否要有相应的动作。

再来举个新浪微博的例子:
写个简单的观察者类模拟观察者:

var Observer = (function(global) {
  var Observer = function(data) {
    this.data = data;
    this.evtHandler = {};
  };

  var op = Observer.prototype;

  op.trigger = function(evt, params) {
    if (!this.evtHandler[evt]) {
      return;
    }

    var callbacks = this.evtHandler[evt];
    for (var i = 0; i < callbacks.length; i++) {
      callbacks[i](params);
    }
  };

  op.registObserver = function(evt, callback) {
    if (!this.evtHandler[evt]) {
      this.evtHandler[evt] = [];
    }
    this.evtHandler[evt].push(callback);
  };

  return Observer;
})(this);

我们可以把输入框作为个被观察者,当我们发布了一条普通的状态,整个页面上会产生哪些变化呢?
1. 右侧的微博条数应该会加一(在微博改版后好像就不会加一了,老版是会加一的)

2. 会产生一条新鲜事

3. 发布框的状态会发生改变,右上角的数字会变为140

通过代码的方式,可以如下表示出来

var handler = new Observer();

handler.registObserver('publishUGC', function() {
   // 请求一次新鲜事,并且更新界面
   // ...
})
handler.registObserver('publishUGC', function() {
   // 改变发布框的状态(更新可发布文字)
   // ...
})

handler.registObserver('publishUGC', function() {
   // 
})

这时候你肯定会想,这么做有什么好处呢。代码的复杂度上升了,若是直接在调用了发送新鲜事的接口的回调中几十来行的代码把上诉的1,2,3立即给解决了岂不是更爽?
各路看官应该都会有自己的看法,我的看法如下两点:

  1. 模块之间最大程度的得到了解耦 随着前端的代码结构的越来越复杂,很多团队在开发时候都采用了模块化的方式。使用观察者模式,使代码达到解耦的优势也自然体现出来。
  2. 便于开发人员后续的维护 面向对象编程有个很经典的观点,增加原有系统的功能最好的方式是扩展他,而不是去修改他。 观察者模式做到了能把系统用扩展的方式来增加功能,而不需要在代码中一遍遍的修改,改到最后变得一团糟,最后变得难以维护坑爹骂娘的吐槽着极品的前任(有木有淡淡躺枪的感觉?)。
  3. (欢迎补充或者拍砖)

现在流行的web框架backbone.js,是使用观察者模式的一个很经典的例子,将模型(Module)和视图(View)的修改进行绑定。
改变了模型,绑定在这个模型上的一个或者多个相应的视图也会跟着进行改变。

写的有点乱。
最后的吐槽:
原来的Wordpress网站botobe.com被停掉了,可4我一直在用他的代码排版格式化插件啊!知晓第一时间内为毛有种菊花一紧的赶脚?!
看来我连格式化代码的功能都要投向Github的的怀抱了。

本文Github链接

2013.09.04
一切安好。
Merci !