5

Observer和Mediator模式的区别

 3 years ago
source link: https://segmentfault.com/a/1190000009156621
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Observer观察者模式

Observer观察者模式和Pub/sub模式事实上都是同一套路。这种模式建立起了不同对象之间的依赖关系:

图片描述

当一个对象触发某个方法,或者发生变化时,其他关注这个对象的对象们,也会响应这个对象的变化。

    function setObserverBehavior (subjects) {
        if (!Array.isArray(subjects)) {
            if (subjects.length) {
                subjects = Array.from(subjects)
            } else {
                subjects = [subjects]
            }
        }
        
        subjects.forEach(function (subject) {
            subject.watchBy = function (target, type) {
                subject.addEventListener(type, function (evt) {
                    evt.sender = subject
                    evt.recevier = target
                    target.notice && target.notice(evt)
                })
            }
        })
    }
    
    setObserverBehavior(observer)
    // 定义subjectOne对observer的依赖
    observer.watchBy(subjectOne, 'scroll')
    // 定义subjectTwo对observer的依赖
    observer.watchBy(subjectTwo, 'scroll')
    
    // 当observer触发scroll事件的时候,subjectOne会响应这个事件
    subjectOne.notice = function (evt) {
        const { sender, receiver } = evt
        // do something
    }
    
    // 当observer触发scroll事件的时候,subjectTwo会响应这个事件
    subjectTwo.notice = function (evt) {
        const { sender, receiver } = evt
        // do something
    }

显然,在需要建立依赖关系不多的几个对象中,使用Observer模式可以很好的将不同对象之间进行解耦:定义一个被观察者的主体,然后添加观察者对被观察者的依赖关系。但是需要建立依赖关系的对象一旦多起来,那么大家也可以想象下,自己手动去维护这些依赖关系是多么的蛋疼。

Mediator中介者模式

图片描述

基本的套路就是:提供一个中介对象Mediator,这个中介对象就是其他所有对象之间的联系纽带,其他所有对象相互之间没有没有任何的依赖关系,事件的订阅及发布统一让Mediator去操作。其他所有的对象需要做的就是提供给Mediator需要发布的事件,以及订阅Mediator上能提供的事件。

举个例子:

淘宝商铺:卖家A淘宝上开了一个Gopro相机店,b, c, d最近都有意愿去买Gopro,但是觉得价格稍贵,因此暂时不打算入手,想等价格稍微便宜一点后再入手,所以这3个人通过淘宝先关注卖家A的相机店。等到卖家AGopro相机打折后,淘宝会向这3个人推送打折消息。

其中这3个买家之间是没有任何依赖关系的,并不知道对方。当一个买家不打算买这家店的相机,取消关注后,对其他2个买家没有任何影响,唯一不同的是,卖家AGopro相机打折后,淘宝只会通知仍然关注卖家A的2个买家

在这个例子当中:

  • 淘宝: Mediator

  • 卖家A: 发布者

  • 买家B/C/D: 订阅者

发布者通过Mediator去发布消息,Mediator再去通知其他的订阅者

简单的实现:

    class Mediator {
        constructor () {
            this.subscribers = {}
        }
        
        pubNotice (type, obj) {
            this.subscribers[type] = this.subscribers[type] || []
            this.subscribers[type].forEach(sub => {
                sub(obj)
            })
        }
        
        subNotice (type, target, fn) {
            this.subscribers[type] = this.subscribers[type] || []
            this.subscribers[type].push(fn)
        }
    }
    
    const sub1 = {
        sayHi(data) {
        console.log(`sub1 get the data ${data}`)
        }
    }

    const sub2 = {
        sayHi(data) {
            console.log(`sub2 get the data ${data}`)
        } 
    }

    const mediator = new Mediator()

    mediator.subNotice('sayHi', sub1, sub1.sayHi)
    mediator.subNotice('sayHi', sub2, sub2.sayHi)

    mediator.removeNotice('sayHi', sub2, sub2.sayHi)

    mediator.pubNotice('sayHi', '你好')

ObserverMediator实现的套路上来看,二者都有相似之处,就是订阅者订阅发布者发布的消息,但是Observer订阅者发布者直接产生依赖关系,当依赖关系变多起来就不好处理了。而Mediator是在订阅者发布者中间加了一个中介者,由这个中介者去管理不同对象之间的订阅发布关系,这样的好处就是订阅者发布者不产生直接的依赖关系,统一交给中介者去维护。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK