观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的对象。
什么是观察者模式
观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的对象。
有值得关注的状态的对象通常被称为目标,由于它要将自身的状态改变通知给其他对象,我们也将其称为发布者 (publisher),所有希望关注发布者状态变化的其他对象被称为订阅者(subscribers)。
当发布者发布了事件,它要遍历订阅者并调用其对象的特定通知方法。
举例说明观察者模式类似于明星与粉丝的关系,粉丝关注明星,当明星发布消息的时候,粉丝会对这个消息做出反应。
观察者模式适用场景
当一个对象状态的改变需要改变其他对象,可使用观察者模式。
当一些对象必须观察其他对象时,可使用观察者模式。
实现观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class Subject { constructor() { this.observers = [] }
attach(observer) { const isExist = this.observers.includes(observer)
if (isExist) { console.log('观察者已添加') return }
this.observers.push(observer) }
detach(observer) { const index = this.observers.indexOf(observer)
if (index < 0) { console.log('观察者不存在') return }
this.observers.splice(index, 1) }
notify() { for (const observer of this.observers) { observer.update(this) } } }
class Observer { update(subject) {} }
|
一个例子
小明,小红,小安都会留意早餐吃什么,不同的早餐会使他们产生不同的情绪,因此早餐是目标,三人是观察者。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| class Breakfast extends Subject { constructor(element) { super() this.value = '' this.element = element
this.element.addEventListener('change', (event) => { this.value = this.element.value this.notify() }) }
notify() { for (const observer of this.observers) { observer.update(this.value) } } }
class Person extends Observer { constructor(element) { super() this.mood = '' this.element = element }
update(subject) {} }
class Person1 extends Person { update(value) { switch (value) { case 'bread': this.mood = '开心' break case 'noodles': this.mood = '喜悦' break case 'gruel': this.mood = '讨厌' break default: this.mood = '' break } this.element.querySelector('.mood').innerHTML = this.mood } }
class Person2 extends Person { update(value) { switch (value) { case 'bread': this.mood = '讨厌' break case 'noodles': this.mood = '开心' break case 'gruel': this.mood = '还可以' break default: this.mood = '' break } this.element.querySelector('.mood').innerHTML = this.mood } }
class Person3 extends Person { update(value) { switch (value) { case 'bread': this.mood = '不喜欢' break case 'noodles': this.mood = '还可以' break case 'gruel': this.mood = '开心' break default: this.mood = '' break } this.element.querySelector('.mood').innerHTML = this.mood } }
const breakfast = new Breakfast(document.getElementById('breakfast'))
const xiaoming = new Person1(document.getElementById('xiaoming'))
const xiaohong = new Person2(document.getElementById('xiaohong'))
const xiaoan = new Person3(document.getElementById('xiaoan'))
breakfast.attach(xiaoming) breakfast.attach(xiaohong) breakfast.attach(xiaoan)
|
当早餐发生变化时,不同类型的人会根据不同的早餐产生不同的情绪。
See the Pen Observer Pattern by Cold Stone (@xrr2016) on CodePen.