设计模式之观察者模式

观察者模式,又被称为发布-订阅模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能耦合。

虽然说观察者模式,又被称为发布-订阅模式,但是实际上它们之间存在差异的,区别在于调度的地方不同。

上图:

总结

  1. 从两张图片可以看到,最大的区别是调度的地方。虽然两种模式都存在订阅者和发布者(具体观察者可认为是订阅者、具体目标可认为是发布者),但是观察者模式是由具体目标调度的,而发布/订阅模式是统一由调度中心调的,所以观察者模式的订阅者与发布者之间是存在依赖的,而发布/订阅模式则不会。

  2. 两种模式都可以用于松散耦合,改进代码管理和潜在的复用。

代码

观察者模式实现代码

class ObserverList {
  constructor() {
    this.observerList = [];
  }
  add(observer) {
    // todo add observer to list
    return this.observerList.push(observer);
  }
  remove(observer) {
    // todo remove observer from list
    this.observerList = this.observerList.filter(item => item != observer);

  }
  count() {
    // return observer list size
    return this.observerList.length;
  }
  get(index) {
    return this.observerList[index];
  }
}

class Subject {
  constructor() {
    this.observers = new ObserverList();
  }
  addObserver(observer) {
    // todo add observer
    this.observers.add(observer);
  }
  removeObserver(observer) {
    // todo remove observer
    this.observers.remove(observer);
  }
  notify(...args) {
    // todo notify
    let observerCount = this.observers.count();
    for(let i=0; i<observerCount; i++) {
      this.observers.get(i).update(...args);
    }
  }
}

module.exports = { Subject };

发布订阅实现代码

module.exports = class PubSub {

  constructor() {
    this.subscribers = {};
  }

  subscribe(type, fn) {
    // todo subscribe
    if(typeof this.subscribers[type] === 'undefined') {
      this.subscribers[type] = [fn];
    } else {
      this.subscribers[type].push(fn);
    }
  }

  unsubscribe(type, fn) {
    // todo unsubscribe
    let listener = this.subscribers[type];
    if(!listener) {
      return;
    }
    this.subscribers[type] = listener.filter(item => item != fn);

  }

  publish(type, ...args) {
    // todo publish
    let listener = this.subscribers[type];
    if(!listener) {
      return;
    }
    listener.forEach(element => {
      element.call(this, ...args);
    });
  }

}

参考文章

http://www.cnblogs.com/lovesong/p/5272752.html

posted @   莯琂  阅读(97)  评论(0编辑  收藏  举报
编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示