JavaScript设计模式之观察者模式

简介

        观察者模式由称作发布-订阅者模式或消息机制,该模式定义一种依赖关系,旨在解决主体对象与观察者之间功能的耦合。

        例如案例:想实现一个评论模块,当用户发送消息时,在展示模块末尾追加新的评论,同时用户消息模块中的消息数量会相应增加,删除评论时,用户消息模块数量减少。但是该评论模块之前有有多个开发人员参与,模块之间闭包独立,不想让新实现的代码参与到之前的项目代码中,那么观察者模式就是解决该需求的利器。

实现

创建观察者对象

首先需要先创建一个观察者对象,该对象里面有一个消息容器,并且存在订阅消息,取消订阅消息,发送订阅消息这三个动作方法。

var Observer = (function () {
  var _message = {};
  return {
    //注册订阅信息
    register: function () {},
    //取消订阅信息
    remove: function () {},
    //发送订阅信息
    send: function () {},
  };
})();

以上已经形成观察者对象的雏形,接下来就是实现这三个方法了。register作用是将订阅者注册的消息推入消息队列,因此该方法接收两个数,消息类型及相应的处理动作。

 register: function (type, fn) {
      //如果该消息类型尚未存在则先创建一个消息类型
      if (typeof _message[type] === undefined) {
        _message[type] = [fn];
      } else {
        //如果此消息类型存在了,则向该类型的消息序列中推入一条执行方法
        _message[type].push(fn);
      }
    }

send方法作用是当观察者发布一条消息时,将所有订阅者订阅的消息一次性全部执行。该方法接收两个参数,消息类型及动作执行时需要传递的参数。

    send: function (type, args) {
      //校验当前消息队列中有没有注册该类型
      if (!_message[type]) return;
      //定义消息信息
      var events = {
        type: type,
        args: args || {},
      };
      i = 0;
      len = _message[type].length;
      //遍历消息动作
      for (; i < len; i++) {
        //依次执行注册消息对应的动
        _message[type][i].call(this, events);
      }
    }

最后一个功能便是注销方法remove,其功能是将订阅者注销的消息从消息队列中移除,因此我们需要两个参数,消息类型和要执行的某一个动作。

 remove: function (type, fn) {
      //如果该消息动作队列存在
      if (_message[type] instanceof Array) {
        var i = _message[type].length - 1;
        for (; i >= 0; i--) {
          //如果该动作存在则在消息动作序列中移除相应动作
          _message[type][i] == fn && _message[type].splice(i, 1);
        }
      }
    }

三个方法均已经实现,下面就来测试吧

var fn_1 = function (param) {
  console.log("type_1_1", param);
};
var fn_2 = function (param) {
  console.log("type_1_2", param);
};
var fn_3 = function (param) {
  console.log("type_2_1", param);
};
var fn_4 = function (param) {
  console.log("type_2_2", param);
};
Observer.register("type_1", fn_1);
Observer.register("type_1", fn_2);

Observer.register("type_2", fn_3);
Observer.register("type_2", fn_4);

Observer.remove("type_2", fn_4);

Observer.send("type_1", "吃饭啦!");
Observer.send("type_2", "唱k啦");

//打印结果
//type_1_1 {type: "type_1", args: "吃饭啦!"}
//type_1_2 {type: "type_1", args: "吃饭啦!"}
//type_2_1 {type: "type_2", args: "唱k啦"}

代码地址:https://github.com/CcXxWw112233/base_demo/tree/master/designMode/observer

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值