前端设计模式之观察者与发布订阅 | 青训营笔记

·  阅读 14

这是我参与「第四届青训营 」笔记创作活动的的第3天

何为设计模式?

设计模式指在软件开发过程中对于遇到的常见问题的比较通用的解决方案。

常见的设计模式有外观模式代理模式工厂模式单例模式策略模式迭代器模式观察者模式中介者模式发布订阅模式访问者模式等。

本文仅涉及观察者模式和发布订阅模式。

观察者模式

定义

被观察对象(subject)维护一组观察者(observer),当被观察对象状态改变时,通过调用观察者的update方法将这些变化通知到观察者

实现一个观察者模式类

工作流程图如下:

image.png

根据上图的思路,我们可以尝试实现一个观察者类。

class Observer {
  attr = null;
  watch(target, attr) {
    const that = this;
    that.attr = attr;
    Object.defineProperty(target, attr, {
      set: function (newVal) {
        that.update(this[`_${attr}`], newVal);
        this[`_${attr}`] = newVal;
      },
      get: function () {
        return this[attr];
      }
    });
  }
  update(oldVal, newVal) {
    console.log(`${this.attr}属性值由${oldVal}变为${newVal}`);
  }
}

const observer = new Observer();

const target = {
  _a: 1
};

observer.watch(target, 'a');

target.a = 2; //a属性值由1变为2

复制代码

发布订阅模式

发布订阅模式实际上是基于观察者模式的一种改造。

实现发布订阅类

以商品的到货通知为例展开实现:

class Shop {
    constructor() {
        this.repository = {};
    }
    // 订阅
    $on(goods, callback) {
        if (!this.repository[goods]) {
            this.repository[goods] = [];
        }
        this.repository[goods].push(callback);
    }
    // 发布
    $emit(goods) {
        if (this.repository[goods] && this.repository[goods].length) {
            this.repository[goods].forEach((cb) => cb(goods));
        } else {
            console.log('该商品没有客户订阅');
        }
    }
    // 取消订阅
    $removeSubscribe(goods, callback) {
        if (this.repository[goods]) {
            this.repository[goods] = this.repository[goods].filter(
                (cb) => cb != callback
            );
            console.log('取消订阅成功');
        }
    }
    // 一次性订阅
    $once(goods, callback) {
        let fn = (goods) => {
            callback(goods);
            this.$removeSubscribe(goods, fn);
        };
        this.$on(goods, fn);
    }
}

var shop = new Shop();
shop.$on('电脑', function(goods) {
    console.log(`${goods}货到啦!`);
});

shop.$once('鼠标', function(goods) {
    console.log(`${goods}货到啦!`);
});

shop.$emit('电脑');
shop.$emit('鼠标');
shop.$emit('鼠标');
复制代码

总结

  • 这两种设计模式在前端领域有着许多应用场景,比如Vue的响应式实现;

  • 观察者模式与发布订阅模式的区别在于:观察者模式是一对多关系,而发布订阅模式则是多对多关系。

分类:
阅读
标签:
收藏成功!
已添加到「」, 点击更改