什么是观察者模式
定义
- 关于定义,最准确的莫过于Head First设计模式中写到的。
观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监听一个主题对象。这样一来,当被观察者状态发生改变时,需要通知相应的观察者,使这些观察者对象能够自动更新。
关键要素
主题和观察者
主题是观察者观察的对象,也就是被观察者。
观察者观察主题,当主题发生变化,收到通知进行具体的处理。
- 被观察者提供维护观察者的一系列方法
- 观察者提供更新接口
- 观察者把自己注册到观察者里
- 在被观察者发生变化时候,调用观察者的更新方法
举个栗子,代码实现
class Star {
constructor(name) {
this.name = name;
this.state = '';
this.observers = [];
}
getState() {
return this.state;
}
setState(state) {
this.state = state;
this.notityAllObservers();
}
attach(observer) {
this.observers.push(observer);
}
notityAllObservers() {
if (this.observers.length > 0) {
this.observers.forEach(observer => observer.update());
}
}
}
class Fan {
constructor(name, star) {
this.name = name;
this.star = star;
this.star.attach(this);
}
update() {
console.log(`${this.name}说我的爱豆喜欢${this.star.getState()},我也喜欢`);
}
}
let star = new Star('baby');
let fan1 = new Fan('小明', star);
let fan2 = new Fan('小红', star);
star.setState('绿色');
解析:小明和小红(观察者)通过attach()方法把自己加入到baby(被观察者)的数组中,当被观察者的状态改变了,会调用notityAllObservers()方法通知所有观察者的执行update方法,更新自己的状态。
常用场景
- 事件监听addEventListener
<body>
<button id="clickMe">点击我</button>
</body>
<script>
//监听一个事件等待事件发生,执行回调函数 典型的观察者模式~
let btn = document.querySelector('#clickMe');
function onClick() {
alert('click');
}
btn.addEventListener('click', onClick);
</script>
- Promises对象
class Promise {
constructor(fn) {
this.successes = [];
let resovle = (data) => {
this.successes.forEach(item => item(data));
}
fn(resovle);
}
then(success) {
this.successes.push(success);
}
}
let p = new Promise((resovle) => {
setTimeout(() => {
resovle('ok')
}, 2000)
})
p.then(data => console.log(data));
- redux
function createStore(reducer) {
let state;
let listeners = [];
function getState() {
return state;
}
function subscribe(listener) {
listeners.push(listener);
}
function dispatch(action) {
state = reducer(state, action);
listeners.forEach(listener => listener());
}
return {
getState,
subscribe,
dispatch,
}
}
以上是对观察者模式的简单分析,欢迎补充。