Что это такое
Паттерн Mediator (посредник) переносит общение между множеством объектов в одно центральное место. Вместо того чтобы каждый знал каждого (а n объектов означают n·n связей), каждый объект знает только посредника, а посредник направляет сообщения.
Пример: чат-комната
Пользователи никогда не хранят ссылки друг на друга. Пользователь отправляет сообщение в комнату; комната доставляет его всем остальным. Вход и выход затрагивают один список, в одном месте.
Все общаются через комнату
Ana знает только комнату; комната знает всех. Правила доставки — пропустить отправителя, позже, возможно, отключение звука или личные сообщения — находятся ровно в одном методе.
Вывод: программа на Go и захваченный вывод
package main
import "fmt"
// Посредник: пользователи никогда не общаются друг с другом напрямую.
type ChatRoom struct {
users []*User
}
func (c *ChatRoom) Join(u *User) {
u.room = c
c.users = append(c.users, u)
}
func (c *ChatRoom) Broadcast(from *User, msg string) {
for _, u := range c.users {
if u != from {
fmt.Println(u.name, "получает от", from.name+":", msg)
}
}
}
type User struct {
name string
room *ChatRoom
}
func (u *User) Send(msg string) {
u.room.Broadcast(u, msg)
}
func main() {
room := &ChatRoom{}
ana := &User{name: "ana"}
ben := &User{name: "ben"}
cleo := &User{name: "cleo"}
room.Join(ana)
room.Join(ben)
room.Join(cleo)
ana.Send("привет всем")
}
Когда его использовать
Используйте, когда много объектов координируют свои действия и сеть «кто кому сообщает» становится слишком плотной — чат-системы, поля формы, которые включают и выключают друг друга, координация в стиле авиадиспетчерской службы.
Не используйте для двух-трёх объектов с простыми связями. Посредник между двумя сторонами — это лишний участник, которого никто не нанимал.
Плюсы и минусы
Плюсы: участники остаются простыми и переиспользуемыми; правила координации читаются в одном месте; добавление участника не затрагивает ничего другого.
Минусы: посредник разрастается — он может незаметно превратиться в огромный тип, который знает всё; весь трафик через одну точку может скрывать издержки производительности.