es6版·观察者模式+发布订阅模式

一、原理图

二、观察者模式

1、手动触发的观察者模式

/*
 * @Author: laifeipeng 
 * @Date: 2019-02-22 15:44:56 
 * @Last Modified by: laifeipeng
 * @Last Modified time: 2019-02-22 16:29:36
 */
/*************** 观察者模式 **************/

// 观察的主题(目标对象),相当于发布者
class Subject {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
    console.log(this.subs)
  }
  removeSub(sub) {
    const idx = this.subs.findIndex(i => i === sub);
    if (idx === -1) {
      console.log('不存在该观察者');
      return;
    }
    this.subs.splice(idx, 1);
  }
  notify() {
    this.subs.forEach(sub => {
      sub.update();// 与观察者原型方法update对应!
    });
  }
}

// 观察人,相当于订阅者
class Observer {
  update() {
    console.log('update');
  }
}

// 测试代码
const subject = new Subject();
const ob = new Observer();
const ob2 = new Observer();
ob2.update = function () { //修改update方法,实现不同逻辑
  console.log('laifeipeng');
}

//目标添加观察者了
subject.addSub(ob);
subject.addSub(ob2);

//目标发布消息调用观察者的更新方法了
subject.notify();
// update
// laifeipeng

subject.removeSub(ob2);  //移除之后就不触发ob2的update了,不再打印`laifeipeng`
subject.notify();
// update

const test = new Observer();
subject.removeSub(test);// 
// 不存在该观察者

复制代码

2、根据内部状态自动触发更新

  • 手动触发有啥用?肯定要根据内部状态更改触发才有用!
  • 增加内部状态变量state并增加对应的getter/setter
/*
 * @Author: laifeipeng 
 * @Date: 2019-02-22 15:44:56 
 * @Last Modified by: laifeipeng
 * @Last Modified time: 2019-02-22 16:29:36
 */
/*************** 观察者模式 **************/

// 观察的主题(目标对象),相当于发布者
class Subject {
  constructor() {
    this.subs = [];
    this.state = "张三";//触发更新的状态
  }
  //新增两个对于name的操作 获取/更新
  getState() {
    return state;
  }
  setState(state) {
    if (this.state === state) {
      console.log('不能设为之前的name,无效');
      return;
    }
    this.state = state;
    this.notify(); // 有更新,触发通知!【原本手动触发通知的,现在根据数据变化来触发】
  }
  addSub(sub) {
    this.subs.push(sub);
    console.log(this.subs)
  }
  removeSub(sub) {
    const idx = this.subs.findIndex(i => i === sub);
    if (idx === -1) {
      console.log('不存在该观察者');
      return;
    }
    this.subs.splice(idx, 1);
  }
  notify() {
    this.subs.forEach(sub => {
      sub.update();// 与观察者原型方法update对应!
    });
  }
}

// 观察人,相当于订阅者
class Observer {
  update() {
    console.log('update');
  }
}

// 测试代码
const subject = new Subject();
const ob = new Observer();
const ob2 = new Observer();
ob2.update = function () { //修改update方法,实现不同逻辑
  console.log('laifeipeng');
}

//目标添加观察者了
subject.addSub(ob);
subject.addSub(ob2);

//目标发布消息调用观察者的更新方法了
// subject.notify(); // 不使用手动触发,通过内部状态的设置来触发
subject.setState('李四');
// update
// laifeipeng

subject.setState('李四');
// 不能设为之前的name,无效

复制代码

3、观察外部的对象

  • 在2的基础上,把内部状态改为外部的对象(变量)。
  • 举例:贪吃蛇页面score分数,根据snake的长度而改变。
  • 下面只写基本的框架,其他自行填充。
// 贪吃蛇
class Snake(){
    constructor(){
        this.length=3;// 初始长度
        // ...其他一系列实例属性
    }
    // ...其他一系列原型方法
}
const snake = new Snake();
//...对snake的各种处理

class Subject {
  constructor(obj) {
    this.subs = [];
    this.state = obj.length;//触发更新的状态
  }
  notify() {
    this.subs.forEach(sub => {
      sub.update(n);// 与观察者原型方法update对应!
    });
  }
  // 其他还是原来的
}

class Observer {
  constructor(obj) {
    this.score = obj.value;//触发更新的状态
  }
  update(n) {
    this.score += n;
  }
}
const subject = new Subject(snake);
const ob = new Observer(document.getElementById('score'));
subject.addSub(ob);

// 大功告成!!!

复制代码

3、发布订阅模式

  • 下次更新
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值