六、观察者模式

2022-06-10 08:13:09 浏览数 (1)

六、观察者模式

观察者模式又叫发布订阅模式或者消息模式。是设计模式中非常著名也是非常重要的一种模式,这种模式一般会定义一个主体和众多的个体,这里的主体可以想象为一个消息中心,里面有各种各样的消息,众多的个体可以订阅不同的消息,当未来消息中心发布某条信息的时候,订阅过他的个体就会等到通知

1、观察者模式例子

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    
    // 消息中心
    var msgCenter = (function () { 
        var _msg = {}; // 存储消息
        /*
            var _msg = {
                'carInfo': [person1.alreadyRegister.carInfo, person2.alreadyRegister.carInfo, person3.alreadyRegister.carInfo, , person5.alreadyRegister.carInfo]
                'newInfo': [person1.alreadyRegister.newInfo, person2.alreadyRegister.newInfo, person3.alreadyRegister.newInfo, , person4.alreadyRegister.newInfo]
            }
        */
        return {
            // 用于订阅一个消息
            register: function(type, fn) { // fn 回调函数
                if (_msg[type]) {
                    _msg[type].push(fn)
                } else {
                    _msg[type] = [fn]
                }
                
            },
            // 用于发布消息
            fire: function(type, args) { // args 发布消息所附带的信息
                if (!_msg[type]) {
                    return
                } 
                var event = {
                    type: type,
                    args: args || {}
                }
                for(var i = 0; i < _msg[type].length; i  ) {
                    _msg[type][i](event)
                }
            },
            // 用于取消订阅的消息
            cancel: function(type, fn) {
                if (!_msg[type]) {
                    return
                }
                for(var i = 0; i < _msg[type].length; i  ) {
                    if (_msg[type][i] === fn) {
                        _msg[type].splice(i, 1)
                        return
                    }
                }
            }
        }
     })()

     function Person() {
         this.alreadyRegister = {};
     }

     Person.prototype.register = function(type, fn) {
         if (this.alreadyRegister[type]) {
             console.log('您已经订阅过这个消息了,请不要重复订阅')
         } else {
            msgCenter.register(type, fn);
            this.alreadyRegister[type] = fn
         }
     }
     Person.prototype.cancel = function (type) { 
         msgCenter.cancel(type, this.alreadyRegister[type])
         delete this.alreadyRegister[type]
      }

      var person1 = new Person()
      var person2 = new Person()
      var person3 = new Person()
      var person4 = new Person()
      var person5 = new Person()

      person1.register('carInfo', function (e) { 
          console.log('person1得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person1.register('newInfo', function (e) { 
          console.log('person1得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person2.register('carInfo', function (e) { 
          console.log('person2得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person2.register('newInfo', function (e) { 
          console.log('person2得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person3.register('carInfo', function (e) { 
          console.log('person3得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person3.register('newInfo', function (e) { 
          console.log('person3得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person4.register('carInfo', function (e) { 
          console.log('person4得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })
      person5.register('newInfo', function (e) { 
          console.log('person5得到了关于'   e.type   '的消息,消息内容是:'   e.args.info);
       })

       msgCenter.fire('carInfo', {info: '新汽车上市!'})
       msgCenter.fire('newInfo', {info: '某某某来了!'})

       person1.register('carInfo', function(e) {
           console.log('test')
       })

       console.log('------------------')

       person1.cancel('carInfo')
       msgCenter.fire('carInfo', { info: '再发一条' })

    </script>
</head>
<body>
    
</body>
</html>

0 人点赞