秋雨
首页
  • HTML
  • CSS
  • JavaScript
设计模式
webpack
  • 前端常识
  • ES
  • React
  • Redux
  • ReactRouter
  • 事件循环
  • 浏览器渲染流程
  • Vue项目性能优化
  • Vue
  • App
Github
首页
  • HTML
  • CSS
  • JavaScript
设计模式
webpack
  • 前端常识
  • ES
  • React
  • Redux
  • ReactRouter
  • 事件循环
  • 浏览器渲染流程
  • Vue项目性能优化
  • Vue
  • App
Github
  • 构造器模式
  • 原型链模式
  • 工厂模式
  • 抽象工厂模式
  • 建造者模式
  • 单例模式
  • 装饰器模式
  • 适配器模式
  • 适配器模式
  • 代理模式
  • 观察者模式
  • 发布订阅模式
  • 模块模式
  • 桥接模式
  • 组合模式
  • 命令模式
  • 命令模式
  • 迭代器模式
  • 职责链模式

简介

观察者模式包含观察目标和观察者两类对象。 一个目标可以有任意属于与之想依赖的观察者,一旦发现观察目标的状态发生改变,所有的观察着都将得到通知。

优势: 目标者与观察者,功能耦合度降低,专注自身功能逻辑,观察者被动接收更新,时间上解耦,实时接收目标者更新状态。

缺点: 观察者模式虽然实现了对象间依赖关系的低耦合,但却不能对事件通知进行细节管控,如'筛选通知','指定主题事件通知'。

ES6

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

  add(observer) {
    this.observers.push(observer);
  }

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

  notify() {
    this.observers.forEach(function (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("kerwin");
const observer2 = new Observer("tiekui");

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

setTimeout(() => {
  subject.remove(observer1);
}, 2000);

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

示例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>观察者模式</title>
    <style>
      .box {
        display: flex;
        height: 500px;
      }
      .box .left {
        width: 150px;
        background-color: skyblue;
      }
      .box .right {
        flex: 1;
        background-color: yellow;
      }
    </style>
  </head>
  <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>

    <script>
      class Subject {
        constructor() {
          this.observers = [];
        }
        add(observer) {
          this.observers.push(observer);
        }
        remove(observer) {
          this.observers = this.observers.filter((item) => item != observer);
        }
        notify(data) {
          this.observers.forEach(function (item) {
            item.update(data);
          });
        }
      }
      class Observer {
        constructor(name) {
          this.ele = document.querySelector(name);
        }
        update(data) {
          this.ele.innerHTML = data;
        }
      }

      const subject = new Subject();

      const observer = new Observer(".bread");
      const observer2 = new Observer(".header");

      subject.add(observer);
      subject.add(observer2);
      let oli = document.querySelectorAll(".left li");
      for (let i = 0; i < oli.length; i++) {
        oli[i].onclick = function () {
          console.log(this.innerHTML);
          subject.notify(this.innerHTML);
        };
      }
    </script>
  </body>
</html>
最后更新:
贡献者: Mrlishizhen
Prev
代理模式
Next
发布订阅模式