Skip to content

观察者模式 #66

@wangjing013

Description

@wangjing013

它定义了对象间的一种一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

现实生活中发布订阅模式

在互联网时代网购是购物的重要途径之一。例如淘宝中某个商品性价比高的,通常它会出现卖断货情况,大家习惯性都会去问客服,它什么时候会有货?客服通常推荐去关注店铺的 补货通知

从上面例子中找出两个主要角色: 店铺客户。它分别对应着发布-订阅模式中的发布者订阅者

现在来捋一捋这关系,店铺与客户之间的关系是一种一对多的关系,当店铺收到仓库中有货源的时候(库存变化),就通知已经订阅了"补货通知"信息的这批人,这是不是跟观察查者模式的定义相吻合。

接下来通过具体实践来理解上面的定义。

在案例中来理解上面定义

首先发布者与订阅者在程序中体现就是两个类。

发布者应该具备什么样的功能? 取决于它要做的事。回顾下上面的案例店铺与客户是一对多的关系,通常要用集合对象来存储 ( list ) 对应的客户从而建立它们之间的关系。同样店铺具有“补货通知”功能( register ),相反它也应具备"取消"功能( unregister )。 当库存有货时就要进行通知功能( notify )。

订阅者应该具备什么样功能?对于客户而言,只要能够根据补货通知(update),完成一系列的购买事项即可。

基于上面的概念,抽象出 发布-订阅模式 对应的代码实现:

// 发布者
class Subject{
  constructor() {
    this.observerList = []
  }
  notifyObservers() {
    this.observerList.forEach((observer) => {
      observer.update()
    })
  }
  registerObserver(observer) {
    this.observerList.push(observer);
  }
  unregisterObserver(observer){
    this.observerList.forEach((item, i) => {
      if (item === observer) {
        this.observerList.splice(i, 1)
      }
    })
  }
}

// 订阅者
class Observer{
  update() {
    console.log("update");
  }
}

现在发布者和订阅者类已经定义好,在具体的业务场景中只要基于这两个类进行扩展就好。回到上面案例,现在通过代码来实现该场景:

// 店铺
class Store extends Subject {
  constructor() {
    super();
    // 库存
    this.list = [];
  }
  setState(list) {
    this.list = list;
    this.notifyObservers();
  }
}

// 客户
class Customer extends Observer {
  constructor() {
    super();
  }
  update() {
    console.log("有货啦");
    this.addCart();
  }

  addCart() {
    console.log("添加购物车成功");
  }
}

下面,执行对应的代码:

const store = new Store();
const customer0 = new Customer();
const customer1 = new Customer();

// 订阅
store.registerObserver(customer0);
store.registerObserver(customer1);
// 更新库存
store.setState([
  {
    goodName: "1"
  },
  {
    goodName: "2"
  }
]);

对应输出如下:

有货啦
添加购物车成功
有货啦
添加购物车成功

通过上面的案例,相信大家对观察者模式定义、使用有了初步的理解。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions