JS设计模式 --- 观察者模式
程序员文章站
2022-08-07 23:35:59
JS设计模式 — 观察者模式又来更新了,昨天学了白贺翔老师的观察者模式,分享一下,直接看代码! Document
JS设计模式 — 观察者模式
又来更新了,昨天学了白贺翔老师的观察者模式,分享一下,直接看代码!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./CommonUtil.js"></script>
</head>
<body>
<script charset="utf-8">
// JS观察者模式:对程序中的某一个对象进行实时观察,当该对象发生变化,进行通知
// 有两个重要的角色:观察者 被观察者
// 经典案例:订报纸(报社(也叫发布者,被观察者),订阅者(观察者))
// 发布者 被观察者
var Publish=function(name){
this.name=name;
this.subscribers=[];//接受所有的订阅者(每一个订阅者都是一个函数类型fn)
};
// Publish类实例对象发布消息的方法
Publish.prototype.deliver=function(news){
var publish=this;//当前实例 当前发布消息的报社
this.subscribers.forEach(function(fn){//把消息发布给这家报社的所有的订阅者
fn(news,publish);
});
return this;//链式编程
};
// 因为所有的订阅者都是函数类型fn,所以直接在Function的原型上添加方法
// 订阅者 观察者 具体的一个订阅者去订阅报纸的方法
Function.prototype.subscriber=function(publish){
var sub=this;//取得当前订阅的报纸的这个人
// 先判断这家报社是否已经存在当前订阅者
// some方法:循环遍历数组的每一个元素,每一个元素读取执行一个函数,如果其中有一个返回true,那整体就返回true
var alreadyExists= publish.subscribers.some(function(item){
return item === sub;
});
if(!alreadyExists){ //如果不为真,表明该订阅者没有在这家报社订阅过
publish.subscribers.push(this); //就添加进去
}
return this;
};
// 订阅者 观察者 具体的一个订阅者去取消订阅报纸的方法
Function.prototype.unsubscriber=function(publish){
var sub=this;//取得当前取消订阅的报纸的这个人
// 先判断当前订阅者是否在这个报社里,如果在,就把他过滤掉
// filter过滤函数:循环遍历数组的每一个元素,每一个元素读取执行一个函数,如果不匹配就过滤(删除)该元素
publish.subscribers=publish.subscribers.filter(function(item){
return item !== sub;//满足的就返回,不满足的就过滤
});
return this;//链式编程
};
window.onload=function(){
// 实例化发布者对象(报社 被观察者)
var pub1=new Publish('第一家报社');
var pub2=new Publish('第二家报社');
var pub3=new Publish('第三家报社');
// 观察者 订阅者接收消息
var sub1=function(news){
document.getElementById('sub1').innerHTML += arguments[1].name + ":" + news + "\n";
};
var sub2=function(news){
document.getElementById('sub2').innerHTML += arguments[1].name + ":" + news + "\n";
};
// 订阅者订阅报纸 执行方法
sub1.subscriber(pub1).subscriber(pub2).subscriber(pub3);
sub2.subscriber(pub1).subscriber(pub2);
// 事件绑定 BH.EventUtil.addHandler(document.getElementById('pub1'),'click',function(){
pub1.deliver(document.getElementById('text1').value);
});
BH.EventUtil.addHandler(document.getElementById('pub2'),'click',function(){
pub2.deliver(document.getElementById('text2').value);
});
BH.EventUtil.addHandler(document.getElementById('pub3'),'click',function(){
pub3.deliver(document.getElementById('text3').value);
});
// 取消订阅
sub2.unsubscriber(pub2);
};
</script>
<input type="button" id="pub1" value="第一家报社" /> <input type="text" id="text1" /><br/>
<input type="button" id="pub2" value="第二家报社" /> <input type="text" id="text2" /><br/>
<input type="button" id="pub3" value="第三家报社" /> <input type="text" id="text3" /><br/>
<textarea id="sub1" cols="30" rows="5"></textarea>
<textarea id="sub2" cols="30" rows="5"></textarea>
</body>
</html>
本文地址:https://blog.csdn.net/zz_xiaojun/article/details/109381320