Паттерн Посредник (Mediator pattern) используется для централизации сложных взаимодействий и управляющих операций между объектами. Использование данного паттерна позволяет снизить количество зависимостей между объектами в системе (так называемые - коллеги), а взаимодействие между ними осуществляет непосредственно специальный объект (посредник или медиатор). Это улучшает сопровождение кода, так как мы всегда можем реализовать посредник с требуемыми критериями. Данный паттерн относится к поведенческим паттернам. В самом простом виде диаграмма классов данного паттерна выглядит следующим образом.
Заметим, что коллеги знают только о посреднике, в котором инкапсулирована логика взаимодействия. При возрастании объектов в системе данная логика может усложниться, что является одним из минусов паттерна. Рассмотрим ряд пример реализации данного паттерна. Пример первый. В системе имеются пользователи, необходимо наладить между ними общение, например в виде чата. Одна из реализаций.
/* Colleagues */
var User = function (mediator, name) {
this.mediator = mediator;
this.name = name;
};
User.prototype.send = function (msg) {
console.log(this.name + ": sending message: " + msg);
this.mediator.sendMessage(msg, this);
};
User.prototype.receive = function (msg) {
console.log(this.name + ": received message: " + msg);
};
/* ConcreteMediator */
var chatMediator = {
users: [],
addUser: function (user) {
this.users.push(user);
},
sendMessage: function (msg, user) {
for (var i = 0; i < this.users.length; i++) {
if (this.users[i] !== user) {
this.users[i].receive(msg);
}
}
}
};
var Adam = new User(chatMediator, "Adam");
var Poll = new User(chatMediator, "Poll");
var Jon = new User(chatMediator, "Jon");
var Allan = new User(chatMediator, "Allan");
chatMediator.addUser(Adam);
chatMediator.addUser(Poll);
chatMediator.addUser(Jon);
chatMediator.addUser(Allan);
Adam.send("Hi All");
На выходе:
Adam: sending message: Hi All
Poll: received message: Hi All
Jon: received message: Hi All
Allan: received message: Hi All
Пример второй. Ниже будет представлена реализация простой игры - два игрока в течении 30 секунд должны нажимать свою кнопку (1 или 2), по окончании времени побеждает тот, кто успел нажать как можно больше раз. В реализации игры будут участвовать объекты-коллеги и посредник, которые представлены на следующем рисунке.
/* Colleagues */
var Player = function (name) {
this.points = 0;
this.name = name;
};
Player.prototype.play = function () {
this.points += 1;
mediator.played();
};
/* ConcreteColleague */
var scoreboard = {
// element of HTML, which should be updated
element: document.getElementById('results'),
// updates the score on the screen
update: function (score) {
var i, msg = '';
for (i in score) {
if (score.hasOwnProperty(i)) {
msg += '<p><strong>' + i + '<\/strong>';
msg += score[i];
msg += '<\/p>';
}
}
this.element.innerHTML = msg;
}
};
/* ConcreteMediator */
var mediator = {
// all players
players: {},
// initialization
setup: function () {
var players = this.players;
players.home = new Player('Home');
players.guest = new Player('Guest');
},
// updates the score, if someone of the players made the move
played: function () {
var players = this.players,
score = {
Home: players.home.points,
Guest: players.guest.points
};
scoreboard.update(score);
},
// handler of user actions
keypress: function (e) {
e = e || window.event; // IE
if (e.which === 49) { // key "1"
mediator.players.home.play();
return;
}
if (e.which === 48) { // key "0"
mediator.players.guest.play();
return;
}
}
};
/* testing */
var Application = function () {
this.run = function () {
// Start!
mediator.setup();
window.onkeypress = mediator.keypress;
// The game ends after 30 seconds
setTimeout(function () {
window.onkeypress = null;
alert('Game over!');
}, 30000);
};
};
var game = new Application;
game.run();
Приятной Вам игры :)