观察者模式即发布-订阅者模式或消息机制,定义了一种依赖关系,解决主题对象与观察者之间功能的耦合。
一、观察者模式实现
1、实例代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta charset="utf-8">
<style>
div {
margin-top: 5px;
border:solid 1px blue;
padding: 5px;
}
</style>
</head>
<body>
<script type="text/javascript">
//将观察者放在闭包中,当页面加载就立即执行
var Observer = (function(){
var __messages = {};//防止队列消息暴漏而被篡改
return {
regist:function(type,fn){
if(typeof __messages[type] === 'undefined'){
__messages[type] = [fn];
} else __messages[type].push(fn);
},
fire:function(type,args){
if(!__messages[type])return;
var events = {
type:type,
args:args||{}
},
i=0,
len = __messages[type].length;
for(;i<len;i++){
__messages[type][i].call(this,events);//执行注册时的动作
}
},
remove:function(type,fn){
if(__messages[type] instanceof Array){
var i = __messages[type].length - 1;
for(;i>=0;i--){
__messages[type][i] === fn && __messages[type].splice(i,1);
}
}
}
}
})();
Observer.regist('test',function(e){
console.log(e.type+"-->"+e.args.msg);
});
Observer.fire('test',{msg:"传递参数"});
</script>
</body>
</html>
2、执行结果
test-->传递参数
二、解决对象间接偶
举例:学生与老师,学生类是被提问对象,老师是提问对象。
1、代码实现
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta charset="utf-8">
<style>
div {
margin-top: 5px;
border:solid 1px blue;
padding: 5px;
}
</style>
</head>
<body>
<script type="text/javascript">
//将观察者放在闭包中,当页面加载就立即执行
var Observer = (function(){
var __messages = {};//防止队列消息暴漏而被篡改
return {
regist:function(type,fn){
if(typeof __messages[type] === 'undefined'){
__messages[type] = [fn];
} else __messages[type].push(fn);
},
fire:function(type,args){
if(!__messages[type])return;
var events = {
type:type,
args:args||{}
},
i=0,
len = __messages[type].length;
for(;i<len;i++){
__messages[type][i].call(this,events);//执行注册时的动作
}
},
remove:function(type,fn){
if(__messages[type] instanceof Array){
var i = __messages[type].length - 1;
for(;i>=0;i--){
__messages[type][i] === fn && __messages[type].splice(i,1);
}
}
}
}
})();
var Student = function(result){
var that = this;
that.result = result;//回答问题的结果
that.say = function(){
console.log("回答结果:"+that.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.fire(question);
}
//测试一下
var student1 = new Student("学生1回答问题"),
student2 = new Student("学生2回答问题"),
student3 = new Student("学生3回答问题");
//定义每个学生回答问题的类型
student1.answer("什么是设计模式");
student1.answer("简述观察者模式");
student2.answer("什么是设计模式");
student3.answer("什么是设计模式");
student3.answer("简述观察者模式");
//让student3睡一会,此时不能回答问题
student3.sleep("简述观察者模式");
var teacher = new Teacher();
teacher.ask("什么是设计模式");
teacher.ask("简述观察者模式");
</script>
</body>
</html>
2、执行结果
学生3回答问题 简述观察者模式 已被注销
问题是:什么是设计模式
回答结果:学生1回答问题
回答结果:学生2回答问题
回答结果:学生3回答问题
问题是:简述观察者模式
回答结果:学生1回答问题
观察者模式演示完毕。