初面网初面网

观察者模式

包含观察目标和观察者两类对象。

一个目标可以有多个观察者。

目标状态变化,所有观察者都得到通知。

观察者模式缺点在于它的触发没法细分。

class Subject{
  constructor(){
    this.observers = []
  }

  add(observer){
    this.ovservers.push(ovserver)
  }

  remove(observer){
    this.observers = this.observers.filter(item=>item !== observer)
  }

  notify(){
    this.observers.forEach(item=>{
        console.log(item)
        item.update()
    })
  }
}

class Observer{
  constructor(name){
    this.name = name
  }
  update(){
    console.log("update", this.name)
  }
}

const subject = new Subject()
const observer1 = new Observer("tom")
const observer2 = new Observer("tony")

subject.add(observer1)
subject.add(observer2)

setTimeout(()=>{
  subject.remove(observer2)
}, 1000)

setTimeout(()=>{
  subject.notify()
}, 2000)

小例子

实现面包屑功能。头部、主体都有面包屑,点击侧边栏,面包屑里的字变化

/*
// body部分
<header class="header">
  路径
</header>

<div class="box">
  <div class="left">
    <ul>
      <li>首页</li>
      <li>用户管理</li>
      <li>权限管理</li>
      <li>新闻管理</li>
    </ul>
  </div>

  <div class="right">
    <div class="bread"></div>
  </div>
</div>
*/

class Subject{
  constructor(){
    this.observers = []
  }

  add(observer){
    this.ovservers.push(ovserver)
  }

  remove(observer){
    this.observers = this.observers.filter(item => item !== observer)
  }

  notify(){
    this.observers.forEach(item=>{
        // console.log(item)
        item.update(data)
    })
  }
}

class Observer{
  constructor(name){
    this.ele = document.querySelector(name)
  }
  update(data){
    // console.log("update", this.name)
    this.ele.innerHTML = data
  }
}

const subject = new Subject()
const observer1 = new Observer(".bread")
const observer2 = new Observer(".header")

subject.add(observer1)
subject.add(observer2)

let oli = document.querySelectorAll(".left li")
for(let i = 0; i < oli.length; i++){
  oli[i].onclick = function(){
    subject.notify(this.innerHTML)
  }
}

更新于 2025/2/26