大熊君说说JS与设计模式之------中介者模式Mediator
一,总体概要
1,笔者浅谈
我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介。租房者并不关心他租谁的房。房东出租者也不关心他租给谁。因为有中介的存在,这场交易才变得如此方便。
在软件的开发过程中,势必会碰到这样一种情况,多个类或多个子系统相互交互,而且交互很繁琐,导致每个类都必须知道他需要交互的类,这样它们的耦合会显得异常厉害。牵一发而动全身,后果很严重,大熊很生气!~~~~(>_<)~~~~
好了,既然问题提出来了,那有请我们这期的主角------中介者模式出场吧
中介者的功能就是封装对象之间的交互。如果一个对象的操作会引起其他相关对象的变化,而这个对象又不希望自己来处理这些关系,那么就可以去找中介者,让它来处理这些麻烦的关系。看下面的小例子:
1 var Participant = function(name) { 2 this.name = name; 3 this.chatroom = null; 4 }; 5 Participant.prototype = { 6 send: function(message, to) { 7 this.chatroom.send(message, this, to); 8 }, 9 receive: function(message, from) { 10 log.add(from.name + " to " + this.name + ": " + message); 11 } 12 }; 13 var Chatroom = function() { 14 var participants = {}; 15 16 return { 17 18 register: function(participant) { 19 participants[participant.name] = participant; 20 participant.chatroom = this; 21 }, 22 23 send: function(message, from, to) { 24 if (to) { 25 to.receive(message, from); 26 } else { 27 for (key in participants) { 28 if (participants[key] !== from) { 29 participants[key].receive(message, from); 30 } 31 } 32 } 33 } 34 }; 35 }; 36 var log = (function() { 37 var log = ""; 38 39 return { 40 add: function(msg) { log += msg + "\n"; }, 41 show: function() { alert(log); log = ""; } 42 } 43 })(); 44 45 function run() { 46 var yoko = new Participant("Yoko"); 47 var john = new Participant("John"); 48 var paul = new Participant("Paul"); 49 var ringo = new Participant("Ringo"); 50 var chatroom = new Chatroom(); 51 chatroom.register(yoko); 52 chatroom.register(john); 53 chatroom.register(paul); 54 chatroom.register(ringo); 55 yoko.send("All you need is love."); 56 yoko.send("I love you John."); 57 john.send("Hey, no need to broadcast", yoko); 58 paul.send("Ha, I heard that!"); 59 ringo.send("Paul, what do you think?", paul); 60 log.show(); 61 }
在示例代码中我们有四个参与者,加入聊天会话通过注册一个聊天室(中介)。每个参与者的参与对象的代表。参与者相互发送消息和聊天室的处理路由。
这里的聊天室对象就起到了中介的作用,协调其他的对象,进行合理的组织,降低耦合。
二,源码案例参考
我们应该很熟悉MVC三层模型实体模型(Model)、视图表现层(View)还有控制层(Control/Mediator)。
控制层便是位于表现层与模型层之间的中介者。笼统地说MVC也算是中介者模式在框架设计中的一个应用。
三,案例引入
1 function Player(name) { 2 this.points = 0; 3 this.name = name; 4 } 5 Player.prototype.play = function () { 6 this.points += 1; 7 mediator.played(); 8 }; 9 var scoreboard = { 10 element:document.getElementById('results'), 11 update:function (score) { 12 var i, msg = ''; 13 for (i in score) { 14 if (score.hasOwnProperty(i)) { 15 msg += '<p><strong>' + i + '<\/strong>: '; 16 msg += score[i]; 17 msg += '<\/p>'; 18 } 19 } 20 this.element.innerHTML = msg; 21 } 22 }; 23 var mediator = { 24 players:{}, 25 setup:function () { 26 var players = this.players; 27 players.home = new Player('Home'); 28 players.guest = new Player('Guest'); 29 }, 30 played:function () { 31 var players = this.players, 32 score = { 33 Home:players.home.points, 34 Guest:players.guest.points 35 }; 36 scoreboard.update(score); 37 }, 38 keypress:function (e) { 39 e = e || window.event; 40 if (e.which === 49) { 41 mediator.players.home.play(); 42 return; 43 } 44 if (e.which === 48) { 45 mediator.players.guest.play(); 46 return; 47 } 48 } 49 }; 50 mediator.setup(); 51 window.onkeypress = mediator.keypress; 52 setTimeout(function () { 53 window.onkeypress = null; 54 console.log('Game over!'); 55 }, 30000);
四,总结一下
Why Mediator ?
各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉及到修改很多其他对象的行为,
如果使用Mediator模式,可以使各个对象间的耦合松散,只需关心和 Mediator的关系,使多对多的关系变成了一对多的关系,
可以降低系统的复杂性,提高可修改扩展性。
使用中介者模式的场合
1.一组定义良好的对象,现在要进行复杂的通信。
2.定制一个分布在多个类中的行为,而又不想生成太多的子类。
可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。(迪米特法则的具体实现)
使用中介者模式的优点:
1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。
2.提高系统的灵活性,使得系统易于扩展和维护。
使用中介者模式的缺点:
中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。
哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步。。。。。。呼呼呼……(*^__^*)