目标者和观察者为一对多关系,目标发生改变时,可以通知到所有观察该目标的观察者。
目标者
目标者构造函数中需要一个列表,用于储存观察者。
1)添加观察者到观察者列表
2)从观察者列表中移除指定观察者
3)更新时通知观察者
也就是说目标者的功能就是管理观察者,并且可以向观察者发布信息
观察者
观察者需要一个id或者name,以此区分不同的观察者
方法即更新时观察者需要做出的策略
简单的观察者模式实例,这是在浏览器运行的js,包含了部分dom操作
class Target {
// 观察者列表
constructor() {
this.obsList = []
}
// 新增观察者
add(obs) {
this.obsList.push(obs)
}
// 移除观察者
remove(obs) {
let index = this.obsList.findIndex(item=> item.name = obs.name)
// 找不到需要移除的观察者就返回
if(index == -1){
return
}
for(let i = index; i < this.obsList.length; i++){
this.obsList[i] = this.obsList[i + 1]
}
this.obsList.pop()
}
// 通知观察者
notify() {
for(let obs of this.obsList){
obs.update()
}
}
}
class Observer {
constructor(name) {
this.name = name
}
// 收到更新消息后触发,这里只打印收到跟新,其实可以做很多操作
update() {
console.log(this.name + '收到了更新')
}
}
// 实例化目标者
let target = new Target()
// 点击按钮添加订阅者
document.querySelectorAll('button')[0].onclick = function() {
let val = document.querySelector('input').value
if(!val){
val = '匿名'
}
target.add(new Observer(val))
// 添加完成后清空input框
document.querySelector('input').value = ''
}
// 查看已添加的观察者列表
document.querySelectorAll('button')[1].onclick = function() {
console.log(target.obsList)
}
对应的html文件
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>观察者模式</title>
</head>
<body>
<input type="text" value=''>
<button>添加</button>
<button>查看</button>
<script src="/observer.js"></script>
</body>
</html>