发布订阅模式与观察者模式

483 阅读4分钟

在开始敲代码之后,设计模式已经听了很多,总有一个感觉,这是很高大上的东西。其实设计模式不只是代码开发在使用,设计模式是一种思想,适用与任何方面。

设计模式高尚一点的说法是:软件设计过程中针对特定问题的简洁优雅的解决方案,简单理解就是:某种场合下针对某个问题的一种解决方案。一定要明白,设计模式并不是直接用来完成代码编写,是一种思想,不是一种死的机制。不同语言对于相同的设计模式有不同的实现方法,也有可能并不适用。

我们可能在平时的开发中不知不觉就用上了设计模式,只是我们自己都不清楚,而设计模式也一直在发展,现在已经得到认可的模式有24种,还有很多模式也被提出,只是还需要时间的检验。

观察者模式(Observer Pattern):

一种一对多的依赖关系,当一个对象发生改变,所有依赖这个对象的都将得到通知,并更新。观察者直接订阅主题,当主题发生变更,直接通知观察者。

发布订阅模式(Publish/Subscribe Pattern):

起初发布订阅模式也叫观察者模式的别名,慢慢的独立成一个不同的设计模式。订阅者把想订阅的事件注册到中间代理,发布者发布事件到中间代理,由中间代理统一发送给订阅者。

观察者模式的观察者相当于发布订阅模式的订阅者,两者的最大区别就是发布订阅模式有了一个中间机制。观察者模式当对象状态发生改变,直接通知观察者,所以对象和观察者是松散的耦合在一起的,而且是同步实现。而发布订阅模式不需要有任何关联,是完全解耦的,都是通过中间机制进行通信,两者是完全分离的,所以也是异步实现。

先上一个观察者模式的代码:

  function User(name) {
    this.name = name;
    this.list = [];
  }

  User.prototype.subscribe = function (target) {
    console.log(this.name + '订阅了:' + target.name);
    target.list.push({target: target.name,user: this.name});
  }

  User.prototype.publish = function () {
    console.log(this.name + '发布了一条消息');
    this.list.forEach((item) => {
      console.log('订阅了' + item.target + '的' + item.user + '收到了这条消息');
    });
  }

  var user1 = new User('用户1');
  var user2 = new User('用户2');
  var user3 = new User('用户3');

  user1.subscribe(user3);
  user2.subscribe(user3);
  user3.publish();

//用户1订阅了:用户3

//用户2订阅了:用户3

//用户3发布了一条消息

//订阅了用户3的用户1收到了这条消息

//订阅了用户3的用户2收到了这条消息

这就是观察者模式,观察者关联了目标对象(user3),当目标对象发布消息的时候,会通知给观察者。

订阅发布模式:

var Mit = {

  typeList: Object.create(null),

  subscribe: function (type, user) {

    if(!this.typeList[type]){

      this.typeList[type] = [];

    };

    this.typeList[type].push({type:type, user: user});

  },

  publish: function (type, user) {

    if(this.typeList[type]){

      for(let item of this.typeList[type]){

         console.log(item.user.name + '接收到了' + user.name + '发布的' + item.type + '类型新闻');

       }

    }

  }

}

function User(name) {

    this.name = name;

}

User.prototype.publish = function (type, user) {

  console.log(this.name + '用户' + '发布了' + type + '类型的新闻');

  Mit.publish(type, user);

}

User.prototype.subscribe = function (type, user) {

    console.log(this.name + '用户' + '订阅了' + type + '类型的新闻');

    Mit.subscribe(type, user);

}

var user1 = new User('user1');

var user2 = new User('user2');

var user3 = new User('user3');

user1.subscribe('type1', user1);

user2.subscribe('type2', user2);

user3.publish('type1', user3);

//user1用户订阅了type1类型的新闻

//user2用户订阅了type2类型的新闻

//user3用户发布了type1类型的新闻

//user1接收到了user3发布的type1类型新闻

有一个中间代理机制,用户之间只存在发布和订阅。

这只是最简单的两个模式,关于订阅发布模式有个很容易让人明白的例子,就算售楼的例子,感兴趣的可以去查看看。

其实观察者模式和发布订阅模式到底是不是同一个的问题,出现了很大的争议,关键在于你怎么区分设计模式了,是看设计意图还是设计结构。如果从结构上看,绝对是不一样的,如果是意图上看,又是一样的。

对于观察者模式和发布订阅模式大概就理解到这样的程度了,至于怎么在编程中使用,就有待商榷了。