javascript设计模式之Mediator(中介者)模式
来源:互联网 发布:6603棋牌 数据库 编辑:程序博客网 时间:2024/06/05 10:41
关于设计模式
设计模式是起源于建筑学, 某些情况下理论与实践的结合才是最好的, 从实践中不断地总结然后形成一个知识体系,为我们后面学习的人提供了很好的思路和解决方案, 同时我们也可以少走很多弯路,我们下面就来看常用设计模式中的一种--------中介者设计模式, 这只是学习过程中的一个记录,欢迎大神指点微笑
一、什么是中介者模式
中介者模式是一种行为设计模式,它允许我们公开一个统一的接口,系统中的不同部分可以通过该接口进行通信。
二、中介者模式的基本实现
/*Mediator模式的简单实现,暴露了publish()和subscribe()来实现*/var mediator = (function () {//存储可被广播或监听的事件 var topics = {};//订阅一个topic, 提供一个回调函数,一旦topic被广播就执行回调函数var subscribe = function (topic, fn) { if(!topics[topic]){ topics[topic] = []; } else { topics[topic].push({context: this, callback: fn}); } return this;};//发布/广播事件到程序的剩余部分var publish = function(topic) { var args; if(!topics[topic]){ return false; } args = Array.prototype.slice.call = function(arguments, 1); for (var i=0; l = topics[topic].length; i < l; i++) { var subscription = topics[topic][i]; subscription.callback.apply(subscription.context, args); } return this;}return { Publish: publish; Subscribe: subscribe; installTo: function (obj){ obj.subscribe = subscribe; obj.publish = publish; }};})();
三、中介者模式的高级实现
*一个Mediator的topic注册实例*///通过生成对象实例,之后我们可以和容易的更新订阅者,而不需要注销并重新注册它们。订阅者可以写成构造函数,该函数接收三个参数:一个可被调用的函数fn, 一个options对象和一个context(上下文)//将context上下文传递给订阅者,默认上下文是windows对象 (function (root){ function guidGenerator(){/*...*/} //订阅者构造函数 function Subscriber(fn, options, context){ if(!this instanceof Subscriber){ return new Subscriber(fn, options, context); } else { //guidGenerator() 是一个函数,用于为订阅者生成GUID, 以便之后很方便的引用它们 //为了简洁,跳过具体实现 this.id = guidGenerator(); this.fn = fn; this.options = options; this.context = context; this.topic = null; } } })(window);//这里传递任何内容, 在此把window对象附加到了Mediator对象上面, 也可以传递给其他对象 //Mediator中的topic 持有了一组回调函数和子topic列表,一旦Mediator.Publish方法在Mediator实例杉被调用时,这些回调函数就会被触发。它还包含用于操作数据列表的方法 //模拟Topic //javascript允许我们使用Function对象作为原型的结合与新对象和构造函数一起调用 function Topic (namespace) { if(!this instanceof Topic){ return new Topic(namespace); } else { this.namespace = namespace || ""; this._callback = []; this._topics = []; this.stopped = false; } } //定义topic 的prototype原型, 包括添加订阅者和获取订阅者的方式 Topic.prototype = { //添加订阅者 AddSubscriber: function (fn, options, context) { var callback = new Subscriber(fn, options, context); this.callbacks.push(callback); callback.topic = this; return callback; }, ... } //StopPropagation() 调用进一步的回调函数StopPropagation: function () { this.stopped = true;},//获取现有的订阅者GetSubscriber: function (identifier) { for(var x = 0, y=this._callbacks.length; x < y; x++){ if(this._callbacks[x].id == identifier || this.callbacks[x].fn == identifier){ return this._callbacks[x]; } } for(var z in this._topics){ if(this._topics.hasOwnProperty(z)){ var sub = this._topics[z].GetSubscriber(identifier); if(sub !== undefined){ return sub; } } }},//根据需要对topic 进行不的操作//添加新的topicAddTopic: function (topic) { this._topics[topic] = new Topic((this.namespace ? this.namespace + ":" : "") + topic);},//检查现有的topicHasTopic: function (topic) { return this._topics.hasOwnProperty(topic);},//获取topicreturnTopic: function (topic) { return this._topics[topic];}//如果不在需要订阅者,可以显式的删除它们RemoveSubscrieber: function (identifier) { if(!identifier){ this._callbacks = []; for(var z in this._topics){ if(this._topics.hasOwnProperty(z)){ this._topics[z].RemoveSubscrieber(identifier); } } } for(var y = 0; x = this._callbacks.length; y < x; y++){ if(this._callbacks[y].fn == identifier || this._callbacks[y].id == identifier){ this._callbacks[y].topic == null; this._callbacks.splice(y, 1); x--; y--; } }},//通过子Topic 递归向订阅者发布(Publish)任意参数Publish: function (data){ for(var y = 0; x =this._callbacks.length; y < x; y++){ var callback = this._callbacks[y], l; callback.fn.apply(callback.context, data); l = this._callbacks.length; if(l < x){ y--; x = l; } } for(var x in this._topics){ if(!this.stopped){ if(this._topics.hasOwnProperty(x)){ this._topics[x].Publish(data); } } } this.stopped = false;};//事件在topic上的注册和移除function Mediator(){ if(!this instanceof Mediator){ return new Mediator(); } else { this._topics = new topic(""); }};//GetTopic根据命名空间返回相应的主题实例//让Mediator 支持用于inbox:messages: new: readMediator.prototype = { GetTopic: function (namespace){ var topic = this._topics; // namespaceHierarchy = namespace.split(":"); if(namespace == ""){ return topic; } if(namespaceHierarchy.length > 0){ for(var i = 0; j = namespaceHierarchy.length; i < j; i++){ if(!topic.HasTopic(namespaceHierarchy[i])){ topic.AddTopic(namespaceHierarchy[i]); } topic = topic.ReturnTopic(namespaceHierarchy[i]); } } return topic; }},//如果Mediator.Subscribe不存在,则创建一个Subscribe: function (topicName, fn, options, context) { var options = options || {}, context = context || {}, topic = this.GetTopic(topicName), sub = topic.AddSubscriber(fn, options, context); return sub; }},//通过给定的订阅者ID/命名函数和topic命名空间返回一个订阅者GetSubscriber: function(identifier, topic){ return this.GetTopic(topic, "").GetSubscriber(identifier);},//通过给定的订阅者ID或命名函数,从给定的命名空间递归删除一个订阅者RemoveSubscrieber: function ( topicName,identifier) { this.GetTopic(topicName).RemoveSubscrieber(identifier);},//Topic向下递归调用Mediator.Publish("inbox:messages:new", args);Publish: function(topicName) { var args = Array.prototype.slice.call(arguments, 1); topic = this.GetTopic(topicName); args.push(topicName); this.GetTopic(topicName).Publish(args);};//将Mediator作为一个对象附加到rootroot.Mediator = Mediator;Mediator.topic = topic;Mediator.Subscriber = Subscriber;
四、中介者模式的典型应用—机场交通控制系统
机场控制塔(中介者)处理飞机的起飞和降落,因为所有通信(监听到或发出的通知)都是从飞机到控制塔,而不是从飞机和飞机直接互相通信的。
Mediator Pattern
![机场交通控制系统的设计模式](http://img.blog.csdn.net/20150802195347145)
五、中介者模式的优点和缺点
- 优点:它能够将系统中的对象或组件之间通信渠道由多对多减少到多对一,由于它的松耦合,所以添加发布者或者订阅者也变得很容易; 即简化了对象之间的交互,减少了子类生成。
- 缺点:在具体中介者类中包含同事之间的交互细节,可能会导致具体中介者类非常复杂,是的系统难以维护。
0 0
- javascript设计模式之Mediator(中介者)模式
- 设计模式之Mediator中介者模式
- 设计模式之中介者模式(Mediator)
- 设计模式之中介者模式,mediator
- 设计模式之中介者模式(Mediator)
- 设计模式之中介者模式(Mediator)
- 设计模式之中介者模式Mediator
- 设计模式之中介者模式(Mediator)
- 设计模式之Mediator(中介者)
- 设计模式之Mediator(中介者)
- 设计模式之Mediator(中介者)
- 设计模式之Mediator(中介者)
- 设计模式之十八------Mediator(中介者)
- 设计模式之Mediator(中介者)
- 设计模式(十九)之Mediator(中介者)
- GOF设计模式之MEDIATOR(中介者)
- Mediator(中介者)设计模式
- 设计模式读书笔记之中介者模式(mediator pattern)
- Save the Trees
- WRL 类库项目模板
- 20150802-泛型
- C语言-VS2010调试tips
- PCA + SVM 人脸识别
- javascript设计模式之Mediator(中介者)模式
- 1067. Sort with Swap(0,*) (25)
- hdoj5327
- java中的I/O流
- HDOJ 1241 Oil Deposits【最大连通块 dfs】
- Android OpenGL ES2.0之光照的学习总结
- 无线网络覆盖
- 小白鼠与毒药解题过程分析
- 设计模式1-单例模式