JS模式之代理模式和中介者模式

代理模式

在代理模式中,一个对象充当另一个对象的借口。它与外观模式的区别之处在于,在外观模式中你所拥有的是多个方法调用的便利方法。代理则介于对象的客户端和对象本身之间,并且对该对象的访问进行保护。

这种模式可能看起来像是额外的开销,但是出于性能因素的考虑它却非常有用。代理充当了某个对象的守护对象,并且试图使本体对象做尽可能少的工作。

范例

在有视频服务器与客户端的通信之间,可以设置一个代理,进行合并多个请求,或者进行缓存,这样可以省去有些额外的开销;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var proxy = {
ids: [],
delay: 50,
timeout: null,
callback: null,
context: null,
makeRequest: function(id, callback, context) {
this.ids.push(id);
this.callback = callback;
this.context = context;
if(!this.timeout) {
this.timeout = setTimeout(function() {
proxy.flush();
}, this.delay)
}
},
flush: function() {
http.makeRequest(this.ids, 'proxy.handler');
this.timeout = null;
this.ids = [];
},
handler: function(data) {
var i, max;
if(parseInt(data.query.count, 10) === 1) {
proxy.callback.call(proxy.context, data.query.results.Video);
return;
}
for(i = 0, max = data.query.results.Video.length; i < max; i += 1) {
proxy.callback.call(proxy.context, data.query.results.Video[i]);
}
}
}

在代理中还可以设置缓存,这样当相同的请求来临时,可以进一步保护对本体对象的http的访问。那么,如果videos对象恰好再一次请求同一个视频,proxy可以从缓存中取出该信息,从而节省了该网络的往返信息。

中介者模式

应用程序中,无论大小都是由一些单个的对象所组成。所有这些对象需要一种方式来实现相互通信,而这种通信方式在一定程度上不降低可维护性,也不损害那种安全的改变部分应用程序儿不会破坏其余部分的能力。随着应用程序的增长,将添加越来越多的对象。然后在代码重构阶段,对象将被删除或重新整理。对对象互相知道太多信息并且直接通信(调用对方的方法并改变属性),这将导致产生不良的紧耦合问题。党对象间紧密耦合时,很难在改变单个对象的同时不影响其他多个对象。因而,即使对应用程序进行最简单的修改也变的不再容易,而且几乎无法估计修改可能话费的时间。

中介者模式缓解了该问题并促进形成松耦合,而且还有助于提高可维护性。在这种模式中,独立的对象之间并不直接通信,而是通过mediator对象。当其中的一个colleague对象改变状态以后,它将会通知该mediator,而mediator将会把该变化传达到任意其他应该知道此变化的colleague对象。

看一个按键游戏,两个玩家看谁按键得分多;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
function Player(name){
this.points = 0;
this.name = name;
}
Player.prototype.play = function() {
this.points += 1;
mediator.played();
}
var coreboard = {
update(score) {
var i, msg = '';
for(i in score) {
msg += `<p><strong>${i}</strong>: ${score[i]}</p>`
}
}
}
var mediator = {
palyers: {},
setup: function() {
var players = this.players;
players.home = new Player('Home');
players.guest = new Player('Guest');
},
played: function(e) {
var players = this.players,
score = {
Home: players.home.points,
Guest: players.guest.points
};
scoreboard.update(score);
},
keypress: function(e) {
e = e || window.event;
if(e.which === 49) {
mediator.players.home.play();
return
}
if(e.which === 48) {
mediator.players.guest.play();
return
}
}
}
// 最后建立以及拆除该游戏
mediator.setup();;
window.onkeypress = mediator.keypress;
setTimeout(function() {
window.onkeypress = null;
alert('Game Over')
}, 30000)