IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    学习观察者模式

    冷石发表于 2022-08-29 09:01:22
    love 0

    观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的对象。

    什么是观察者模式

    观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的对象。

    有值得关注的状态的对象通常被称为目标,由于它要将自身的状态改变通知给其他对象,我们也将其称为发布者 (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)

    // 取消观察
    // breakfast.detach(xiaoan)

    当早餐发生变化时,不同类型的人会根据不同的早餐产生不同的情绪。

    breakfrast

    See the Pen Observer Pattern by Cold Stone (@xrr2016) on CodePen.



沪ICP备19023445号-2号
友情链接