设计模式知识连载(27)---观察者模式:
2017-12-24 01:05
375 查看
<body> <h3>设计模式知识连载(27)---观察者模式:</h3> <p> 又被称作发布-订阅者模式或者消息机制,定义了一种依赖关系, 解决了主体对象与观察者之间功能的耦合 </p> <hr> <div> <div> <ul id = 'msg'> </ul> </div> <div id = 'msg_num'> </div> <form> <input type="text" name="name" value="测试测试这是啥" id = 'user_input'> <button type="button" id = 'user_submit'>点击</button> </form> </div> <script type="text/javascript"> /** * 案例一:,方式一:初始 */ // 将观察者放在闭包中,当页面加载就立即执行 var Observer = (function() { // 防止消息对鞋暴露而被篡改故将消息容器作为静态私有变量保存 var __message = {} ; return { // 注册信息接口 regist : function(type, fn) { // console.log('进入了注册信息接口---regist') ; // 如果此消息不存在则应该创建一个该消息类型 if(typeof __message[type] === 'undefined') { // 将动作推入到该消息对应的动作执行队列中 // console.log('__message:', __message) ; // console.log('__message[type]:', __message[type]) ; // console.log('[fn]:', [fn]) ; __message[type] = [fn] ; // console.log('__message:', __message) ; // console.log('__message[type]:', __message[type]) ; // 如果此消息存在 }else{ // 将动作方法推入该消息对应的动作执行序列中 __message[type].push(fn) ; } // 返回指针 return this ; }, // 发布信息接口 publish : function(type, args) { // console.log('进入了发布信息接口---publish') ; // 如果该消息没有被注册,则返回 if(!__message[type]) { return ; } // 定义消息信息 var events = { type : type, // 消息类型 args : args || {} // 消息携带数据 } // 依次执行注册的消息对应的动作序列 for(var i = 0; i < __message[type].length; i++) { __message[type][i].call(this, events) ; } // 返回指针 return this ; }, // 移除信息接口 remove : function(type, fn) { // console.log('进入了移除信息接口---remove') ; // 如果消息动作队列存在 if(__message[type] instanceof Array) { // 从最后一个消息动作遍历 // console.log(__message[type]) ; // fn // console.log(__message[type].length) ; // 1 var i = __message[type].length - 1 ; for(; i >= 0; i--) { // console.log(fn) ; // console.log(__message[type]) ; // console.log(__message[type][i]) ; // console.log((__message[type].splice(i, 1))[i]) ; // 如果存在该动作则在消息动作序列中移除相应动作 __message[type][i] === fn && __message[type].splice(i, 1) ; } } // 返回指针 return this ; } } })() ; /** * 测试用例: * 1、注册 * 2、发布 * 3、移除 */ // Observer.regist('test111', function(e) { // // console.log('这是regist的回调函数,类型为:test111') ; // console.log('e.type:', e.type + '---e.args.msg:', e.args.msg) ; // console.log('------------------------------------------------') ; // }) ; // Observer.regist('test222', function(e) { // // console.log('这是regist的回调函数,类型为:test222') ; // console.log('e.type:', e.type + '---e.args.msg:', e.args.msg) ; // console.log('------------------------------------------------') ; // }) ; // Observer.regist('test333', function(e) { // // console.log('这是regist的回调函数,类型为:test333') ; // console.log('e.type:', e.type + '---e.args.msg:', e.args.msg) ; // console.log('------------------------------------------------') ; // }) ; // Observer.publish('test111', {msg : '传递参数111'}) ; // Observer.publish('test222', {msg : '传递参数222'}) ; // Observer.publish('test333', {msg : '传递参数333'}) ; // Observer.remove('test111', function() { // console.log('移除消息成功') ; // }) ; /****** *** 测试---------------- ******/ // (function() { // Observer.regist('addCommentMessage', function(e) { // // console.log('执行了工程师A的addCommentMessage方法') ; // console.log('e.type:', e.type) ; // console.log('e.args:', e.args) ; // console.log('----------------') ; // }) ; // })() ; // (function() { // Observer.regist('addCommentMessage', function(e) { // // console.log('执行了工程师B的addCommentMessage方法') ; // console.log('e.type:', e.type) ; // console.log('e.args:', e.args) ; // console.log('----------------') ; // }) ; // Observer.regist('removeCommentMessage', function(e) { // console.log('执行了工程师B的removeCommentMessage方法') ; // }) ; // })() ; // (function() { // var _input = $('user_input') ; // var _value = _input.value ; // $('user_submit').onclick = function() { // var _input = $('user_input') ; // var _value = _input.value ; // console.log('_value:', _value) ; // Observer.publish('addCommentMessage', {text : _value, num : 1}) ; // return false ; // } // Observer.publish('addCommentMessage', {text : _value, num : 1}) ; // })() ; /** * 实例一: */ // 外观模式 简化获取元素 function $(id) { return document.getElementById(id) ; } // 工程师A (function() { // 追加一则消息 function addMsgItem(e) { // 获取消息中用户添加的文本内容 var text = e.args.text ; // 留言容器元素 var _ul = $('msg') ; // 创建内容容器元素 var _li = document.createElement('li') ; // 创建删除按钮 var _span = document.createElement('span') ; // 写入内容 _li.innerHTML = text ; _span.innerHTML = ' x' ; // 关闭按钮事件 _span.onclick = function() { // 移除留言 _ul.removeChild(_li) ; // 发布删除留言消息 Observer.publish('removeCommentMessage', {num : -1}) ; } // 添加删除按钮 _li.appendChild(_span) ; // 添加留言节点 _ul.appendChild(_li) ; } // 注册添加评论信息 Observer.regist('addCommentMessage', addMsgItem) ; })() ; // 工程师B (function() { // 更改用户消息数目 function changeMsgNum(e) { // 获取需要增加的用户消息数目 var _num = e.args.num ; // 增加用户消息数目并写入页面中 var _new_num = $('msg_num').innerHTML ; if(!parseInt(_new_num)) { _new_num = 0 ; } $('msg_num').innerHTML = _num + parseInt(_new_num) ; } // 注册添加评论信息 Observer.regist('addCommentMessage', changeMsgNum) .regist('removeComm 4000 entMessage', changeMsgNum) ; })() ; // 工程师C (function() { // 用户点击提交按钮 $('user_submit').onclick = function () { // 获取用户输入框中的输入信息 var text = $('user_input') ; // 如果消息为空则提交失败 if(text.value === '') { alert('数据不能为空') ; return ; } // 发布一则评论消息 Observer.publish('addCommentMessage', {text : text.value, num : 1}) ; // 将输入框置为空 text.value = '' ; } })() ; /** * 实例二:对象间解耦 */ // 学生类 var Student = function(result) { var me = this ; // 学生回答 me.result = result ; // 学生回答问题动作 me.say = function() { console.log('执行了学生回答问题动作方法say()', me.result) ; } } ; // 学生回答问题方法 Student.prototype.answer = function(question) { // 注册参数问题 Observer.regist(question, this.say) ; } // 学生睡觉,此时不能回答问题了 Student.prototype.sleep = function(question) { console.log(this.result + '。' + question + '已被注销') ; // 取消对老师问题的监听 Observer.remove(question, this.say) ; } // 教师类 var Teacher = function() {} // 教师提问问题的方法 Teacher.prototype.ask = function(question) { console.log('问题是:', question) ; Observer.publish(question) ; } var student_1 = new Student('我是学生1,在听课的') ; var student_2 = new Student('我是学生2,在开小猜的') ; var student_3 = new Student('我是学生3,在睡觉的') ; student_1.answer('什么是设计模式') ; student_1.answer('简述观察者模式') ; student_2.answer('什么是设计模式') ; student_2.answer('简述观察者模式') ; student_3.answer('什么是设计模式') ; student_3.answer('简述观察者模式') ; student_3.sleep('简述观察者模式') ; // 创建教师类 var teacher = new Teacher() ; // 提问两个问题 teacher.ask('什么是设计模式') ; teacher.ask('简述观察者模式') ; </script> </body>
相关文章推荐
- 设计模式知识连载(43)---参与者模式:
- Java设计模式知识学习-----观察者模式
- 设计模式知识连载(28)---状态模式:
- 设计模式知识连载(39)---数据访问对象模式---本地存储DAO
- 设计模式知识连载(14)---工厂方法模式:
- 设计模式知识连载(16)---建造者模式:
- 设计模式知识连载(21)---代理模式:
- 设计模式知识连载(50)---MVVM模式:
- 设计模式知识连载(29)---策略模式:
- 设计模式知识连载(39)---数据访问对象模式---MongoDB
- 设计模式知识连载(20)---适配器模式:
- 设计模式知识连载(5)---继承_1:子类的原型对象-类式继承
- 设计模式知识连载(7)---继承_3:优点结合-组合继承
- 设计模式知识连载(45)---同步模块模式:
- 设计模式知识连载(41)---简单模板模式:
- 设计模式知识连载(48)---MVC模式:
- 设计模式知识连载(23)---桥接模式:
- 设计模式知识连载(32)---访问者模式:
- 设计模式知识连载(37)---链模式:
- 设计模式知识连载(3)---封装_2:闭包