js设计模式之观察者模式

观察者模式又叫做发布-订阅模式,主要功能就是解耦。
有一个实际需求,在新闻评论模块,
这里写图片描述
当我们发布评论时,会在展示评论末尾处追加最新评论,同时消息模块的消息数量也会增加,删除评论留言区的评论时,消息模块数量相应的减少。
但是在项目开发中,往往不同模块由不同的人开发,消息模块,评论模块分别由不同的人开发。这个时候不想将几个独立的模块整合在一起,可以用观察者模式。
下面我们一步一步实现:
1.创建观察者:观察者对象包含一个消息容器,和三个方法,订阅消息方法,取消订阅方法,发送消息的方法。
(1) 注册消息方法作用是将订阅者的消息推送到消息队列中,因此我们需要接受两个参数,消息类型和相应的处理动作。
(2)发布消息功能是当观察者发布一个消息时,将所有消息一次执行。接受两个参数,消息类型和动作执行时需要传进来的参数。
(3)注销消息功能是将消息从消息队列中移除

//将观察者放到闭包中,当页面加载就立即执行
var Observer=(function(){
    //消息容器
    var _message={};
    return {
       //注册消息
        register:function(type,fn){
            //如果消息类型不存在,则创建一个该消息类型,并将该动作推到类型中
            if(typeof _message[type]==='undefined'){
                _message[type]=[fn];
                }else {
                //如果消息类型存在,直接将动作推到相应的类型中
                _message[type].push(fn);
                }
             };
        //发布消息
        fire:function(type,args){
            if(!_message[type])
                return;
            var event={
                type:type,
                args:args||{}
                },
                i=0,
                len=_message[type].length;
                //依次执行注册的消息对应的动作序列
             for(;i<len;i++){
                 _message[type][i].call(this,event)
                 }
            };
        //移除消息
        remove:function(type,fn){
           if(_message[type] instanceof Array){
               var len=_message[type].length-1;
               for(;len>0;len--){
                   _message[type][i]==fn && _message[type].splice(i,1);
                   }
                }
             };
        }
    })()

观察者对象创建后,我们可以先简单测试一下:
首先订阅一条消息:

Observer.register('test',function(){
    console.log(e.type,e.args.msg)};
    )

然后发布一条消息:

Observer.fire('test',{msg:"传递参数"});// test 传递参数

回到我们开始说的需求中,对于追加留言的功能应该放到留言模块中,对于消息增减应该放到消息模块中,留言的提交放到提交模块中。选择用观察者模式开发,首先分析哪些模块注册消息,哪些模块发布消息,发布留言和删除留言是用户主动出发,所以应该是观察者主动发布消息,评论的追加和消息增加是被动触发,所以他应该是观察者订阅消息,这样的话,用户信息模块既是信息的发布者也是信息的接收者,提交模块是发送者,浏览模块是信息的接收者。

function $(id){
    return document.getElementById(id);
    }
 //工程师A
(function(){
    function addMsgItem(e){
        var text = e.args.text,
            ul = $('msg'),
            li = document.createElement('li'),
            span = document.createElement('span');
        li.innerHTML = text;
        //关闭按钮
         ul.removeChild(li);
         //发布删除留言消息
         Observer.fire('removeCommentMessage',{num:-1});
         li.appendChild(span);//添加删除按钮
         ul.appendChild(li);//添加留言节点
        }
     //注册添加评论信息
     Observer.register('addCommentMessage',addMsgItem)  
})()
//工程师B
(function(){
    function changeMsgNum(e){
        var num = e.args.num;
        $('msg_num').innerHTML = parseInt($('msg_num').innerHTML)+num;
        }
    //注册添加评论消息
    Observer.register('addCommentMessage',changeMsgNum)
    .register('removeCommentMessage',changeMsgNum);
})()
//工程师C
(function(){
    $('user_submit').onclick = function(){
        //获取用户输入框中输入的消息
        var text = $('user_input');
        if(text.value === ''){
            return;
            }
        //发布一则评论消息
        Observer.fire('addCommentMessage',{
            text:text.value,
            num:1
            });
            text.value='';//将输入框置为空
         }
})();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值