您的位置:首页 > 其它

设计模式知识连载(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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息