设计模式学习之八-中介者模式

代理模式的使用场景: 多个对象之间有相互依赖关系,为了解决错综复杂的关系,
需要创建个中介者对象来管理他们之间的依赖关系。

场景

比如创建个泡泡堂游戏,4v4对战,分别为红方和蓝方,每一方中的每个队员胜利
或失败,都要通知到其他队员,一方人员全部失败,则表示全队阵亡。

代码:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

function Player( name, teamColor ) {
this.state = 'alive';
this.name = name;
this.teamColor = teamColor;
}

Player.prototype.win = function() {
console.log('winner: ' + this.name);
}

Player.prototype.lose = function() {
console.log(`loser: ${this.name}`);
}

Player.prototype.die = function() {
this.state = 'dead';

playerDirector.receiveMessage('playerDead', this);
}

Player.prototype.remove = function ( ) {
playerDirector.receiveMessage('removePlayer', this);
}

Player.prototype.changeTeam = function ( color ) {
playerDirector.receiveMessage('changeTeam', this, color);
}
const playerFactory = (name, teamColor) => {
const newPlayer = new Player(name, teamColor);

playerDirector.receiveMessage('addPlayer', newPlayer);

return newPlayer;
}

var playerDirector = (function ( ) {
var players = {},
operations = {};

operations.addPlayer = function ( player ) {
var teamColor = player.teamColor;
players[teamColor] = players[teamColor] || [];

players[teamColor].push(player);
}

operations.removePlayer = function ( player ) {
var teamColor = player.teamColor,
teamPlayers = players[teamColor] || [];

teamPlayers.map( (v,i) => {
if(v === player){
teamPlayers.splice(i, 1);
}
})
}

operations.changeTeam = function ( player, newTeamColor ) {
operations.removePlayer(player);
player.teamColor = newTeamColor;
operations.addPlayer(player);
}

operations.playerDead = function ( player ) {
var teamColor = player.teamColor,
teamPlayers = players[teamColor];

var all_dead = true;

if(teamPlayers.some(v => v.state !== 'dead')){
all_dead = false;
}

if(all_dead){
teamPlayers.map(v => {
v.lose();
})

Object.keys(players).map(v => {
if(v !== teamColor){
var teamPlayers = players[v];
teamPlayers.map( k => {
k.win();
})
}
})

}
}

var receiveMessage = function ( ) {
var message = Array.prototype.shift.call(arguments);
operations[message].apply(this, arguments);
}

return{
receiveMessage: receiveMessage
}
})()

var player1 = playerFactory('皮蛋','red');
var player2 = playerFactory('小乖','red');
var player3 = playerFactory('宝宝','red');
var player4 = playerFactory('小强','red');

var player5 = playerFactory('黑妞','blue');
var player6 = playerFactory('葱头','blue');
var player7 = playerFactory('胖墩','blue');
var player8 = playerFactory('海盗','blue');

player1.changeTeam('blue');
player2.die();
player3.die();
player4.die();

在这个案例中,playerDirector是中介对象,负责管理双方队员对象的信息,它内部有2个私有属性,
分别是player玩家对象和operation操作对象。

  • player通过key-value的方式表示红队和蓝队,每个队的队员放到数组中,
1
2
3
4
5

player:{
'red': [player1, player2,...],
'blue': [player5, player6, ...]
}
  • operation中包含了中介者对象的一些操作方法,并对外暴露一个receiveMessage接口来调用
    内部方法。
1
2
3
4
var receiveMessage = function () {
var message = Array.prototype.shift.call(arguments);
operations[message].apply(this, arguments);
}

这样实现起来,对象之间的逻辑关系就比较清晰。所有操作就都由playerDirector来管理。

总结

中介者模式的核心概念是让对象与对象之间尽可能的理清关系,一个对象的改变不会影响到其他对象。把他们之间的逻辑关系交给中介者对象
来处理。不过缺点就是中介者对象会越来越庞大臃肿。