学习JavaScript设计模式(三)

Mediator(中介者)模式

中介者是指协助谈判和解决冲突的中立方。他们允许我们公开一个统一的接口,系统的不同部分可以通过该接口进行通讯。
中介者模式实际上是观察者模式的共享目标。中介者模式通过限制对象严格通过 Mediator 进行通讯。观察者模式创建观察对象,观察者对象向订阅他们的对象发布其感兴趣的事件。
简单原理就是:系统的其他模块不能相互通信,必须通过中介者进行通信。例如我们的飞机场,飞机只管降落和起飞,一切动作都是由机场的控制中心进行调配,通知不同的飞机什么时候起飞,什么时候降落。

简单代码实现:

/**
 * Created by Zang on 2017/3/14.
 */

var Mediator = (function () {
    var topics = {};
    // uuid 标识符生成器
    var generatorUUID = function () {
        var d = new Date().getTime();
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
    };
    // 订阅者构造函数
    var Subscriber = function (namespace, fn) {
        var uuid = generatorUUID();
        if (!topics[namespace]) {
            topics[namespace] = {};
        }
        topics[namespace][uuid] = {
            namespace: namespace,
            uuid: uuid,
            fn: fn
        };
        return uuid;
    };
    // 获取订阅者信息
    var GetSubscriber = function (uuid) {
        var subscriber = null;
        for (var k in topics) {
            if (topics[k][uuid]) {
                subscriber = topics[k][uuid];
            }
        }
        return subscriber;
    };
    // 传播信息
    var Publish = function (namespace, data, from, to) {
        if (!namespace) {
            for (var k in topics) {
                for (var l in topics[k]) {
                    topics[k][l].fn(data, GetSubscriber(from), GetSubscriber(l));
                }
            }
        } else if (!to) {
            for (var k in topics[namespace]) {
                topics[namespace][k].fn(data, GetSubscriber(from), GetSubscriber(k));
            }
        } else {
            topics[namespace][to].fn(data, GetSubscriber(from), GetSubscriber(to));
        }
    };

    return {
        Subscriber: Subscriber,
        Publish: Publish
    };
})();

var fn = function (data, from, to) {
    console.log(from.namespace + ':' + from.uuid + ' 发送消息 :' + data + ' 发送给 ' + to.uuid);
};

// A1的uuid为:97304d19-83bf-467c-b866-b3546e91a1b3
// A2的uuid为:c3d3d371-8ba7-47ca-b8db-5a40b00d9bb2
// B的uuid为:75f26c2c-0f12-4bc3-ace0-f48108148975
var A1 = Mediator.Subscriber('A', fn);
console.log('A1的uuid为:' + A1);
var A2 = Mediator.Subscriber('A', fn);
console.log('A2的uuid为:' + A2);
var B = Mediator.Subscriber('B', fn);
console.log('B的uuid为:' + B);

// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 97304d19-83bf-467c-b866-b3546e91a1b3
// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 c3d3d371-8ba7-47ca-b8db-5a40b00d9bb2
// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 75f26c2c-0f12-4bc3-ace0-f48108148975
Mediator.Publish('', '你好', A1);
// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 97304d19-83bf-467c-b866-b3546e91a1b3
// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 c3d3d371-8ba7-47ca-b8db-5a40b00d9bb2
Mediator.Publish('A', '你好', A1);
// A:97304d19-83bf-467c-b866-b3546e91a1b3 发送消息 :你好 发送给 c3d3d371-8ba7-47ca-b8db-5a40b00d9bb2
Mediator.Publish('A', '你好', A1, A2);
// B:75f26c2c-0f12-4bc3-ace0-f48108148975 发送消息 :你好 发送给 75f26c2c-0f12-4bc3-ace0-f48108148975
Mediator.Publish('B', '你好', B);
// 报错 在B这个命名空间中没有A2
Mediator.Publish('B', '你好', B, A2);

优缺点:
最大的好处是:将系统中的对象和组件之间所需的通信渠道由多对多变为多对一。
最大的缺点是:会引入单一的故障点,很难通过广播确定一个系统如何做出反应。

猜你喜欢

转载自blog.csdn.net/qq_20282263/article/details/62057793
今日推荐