Observer(观察者)模式
观察者模式即,某个对象(subject)维持一系列依赖它(观察者)的对象,将有关状态的任何改变自动通知给它们。
当不再希望某个观察者获得其注册对象发出的通知时,该注册对象可以将它从观察者列表中删除
Subject(观察者容器)
- 维护观察者,添加或删除观察者
// 容器列表,系列功能
class ObserverList {
construcor() {
this.list = []
}
Add(obj) {
if(this.IndexOf(obj) === -1) return this.list.push(obj)
}
Empty() {
this.list = []
}
Count() {
return this.list.length
}
Get(i) {
if (i > -1 && i < this.list.length) {
return this.list[i]
}
}
Insert(obj, i) {
if(this.IndexOf(obj) === -1) this.list.splice(i, 0, obj)
}
Remove(obj, i) {
if (i) this.list.splice(i, 1)
else {
i = this.IndexOf(obj)
this.list.splice(i, 1)
}
}
IndexOf(obj) {
return this.list.findIndex((item) => item == obj)
}
}
// 管理观察者
class Subject {
constructor() {
this.observerList = new ObserverList()
}
AddObserver(observer) {
this.observerList.Add(observer)
}
RemoveObserver(observer) {
this.observerList.Remove(observer)
}
Notify(context) {
const observersCount = this.observerList.Count()
for (let i = 0; i < observersCount; i++) {
this.observerList.Get(i).Update(context)
}
}
}
const Sub = new Subject()
Observer(观察者)
- 具体目标发生改变时需要获得通知的对象,提供一个更新接口
class Observer {
constructor(obj) {
this.target = obj
// 让容器添加当前观察者实例
Sub.AddObserver(this)
}
// 通知观察者更新接口
Update(context) {
if(this.target) this.target.getUpdate(context)
}
}
ConcreteSubject(具体目标)
- 状态改变是向 Observer 发出通知,存储自身状态,实现 Observer 更新接口
<button id='addNewObserver'>Add New Observer checkbox</button>
<input type='checkbox' id='mainCheckbox'></input>
<div id='observersContainer'></div>
const controlCheckbox = document.querySelector('#mainCheckbox'),
addBtn = document.querySelector('#addNewObserver'),
container = document.querySelector('#observersContainer')
addBtn['onclick'] = function() {
// 创建新的具体目标
const check = document.createElement('input')
check.type = 'checkbox'
// 创建新的观察者并添加到容器
new Observer(check)
// 观察者通知更新接口实现
check.getUpdate = function(val) {
this.checked = val
}
container.appendChild(check)
}
// 通知观察者更新
controlCheckbox['onclick'] = function() {
Sub.Notify(this.checked)
}
一个栗子
给当前已存在CheckBox 1添加点击事件,通知观察者更新
点击新增按钮创建观察者并创建一个新的CheckBox,并实现观察者更新接口,接收CheckBox 1状态