Mediator
Mediator (Посредник) — это поведенческий паттерн проектирования, который снижает связанность между компонентами, вынеся их взаимодействие в отдельный объект-посредник. Это позволяет модулям взаимодействовать через центральный узел, не зная напрямую друг о друге.
В сложных системах множество объектов могут взаимодействовать между собой, создавая сложные зависимости. Это усложняет поддержку, тестирование и расширение системы. Mediator помогает:
- Уменьшить зависимость между компонентами
- Централизовать управление взаимодействием
- Упростить тестирование и отладку
- Улучшить расширяемость
Реализация Mediator в Golang
Рассмотрим пример системы чата, где пользователи взаимодействуют через посредника — чат-комнату.
Определение интерфейса Mediator
package main
import "fmt"
// Mediator определяет интерфейс посредника
type Mediator interface {
SendMessage(sender *User, message string)
}
Реализация конкретного Mediator
// ChatRoom — конкретный посредник, управляющий сообщениями пользователей
type ChatRoom struct {
users []*User
}
// Добавление пользователя в чат
func (c *ChatRoom) AddUser(user *User) {
c.users = append(c.users, user)
}
// Отправка сообщения через посредника
func (c *ChatRoom) SendMessage(sender *User, message string) {
for _, user := range c.users {
if user != sender {
user.ReceiveMessage(message)
}
}
}Определение участников
// User представляет участника чата
type User struct {
name string
mediator Mediator
}
// Отправка сообщения через посредника
func (u *User) SendMessage(message string) {
fmt.Printf("%s отправляет сообщение: %s\n", u.name, message)
u.mediator.SendMessage(u, message)
}
// Получение сообщения
func (u *User) ReceiveMessage(message string) {
fmt.Printf("%s получил сообщение: %s\n", u.name, message)
}Использование Mediator
func main() {
chatRoom := &ChatRoom{}
user1 := &User{name: "Alice", mediator: chatRoom}
user2 := &User{name: "Bob", mediator: chatRoom}
user3 := &User{name: "Charlie", mediator: chatRoom}
chatRoom.AddUser(user1)
chatRoom.AddUser(user2)
chatRoom.AddUser(user3)
user1.SendMessage("Привет, всем!")
user2.SendMessage("Привет, Alice!")
}Результат работы
Alice отправляет сообщение: Привет, всем! Bob получил сообщение: Привет, всем! Charlie получил сообщение: Привет, всем! Bob отправляет сообщение: Привет, Alice! Alice получил сообщение: Привет, Alice! Charlie получил сообщение: Привет, Alice!
Плюсы и минусы Mediator
Плюсы:
Уменьшает связанность между модулями
Упрощает поддержку и расширение системы
Улучшает читаемость и поддержку кода
Упрощает тестирование отдельных компонентов
Минусы:
Может привести к усложнению логики в посреднике
Может стать узким местом при высокой нагрузке
Заключение
Паттерн Mediator полезен, когда нужно управлять сложными взаимодействиями между объектами, минимизируя их связанность. В Golang его можно реализовать с использованием интерфейсов и конкретных типов, как показано в примере. Используйте его, если компоненты вашей системы сильно связаны друг с другом и требуют упрощения взаимодействий.
Пример реализации
Пример использования
- Command -> Mediator -> Command Handler
- Query -> Mediator -> Query Handler
- Domain Event -> Mediator -> Domain Event Handler
По любым вопросам обращайтесь в комментариях к уроку или в Telegram
Если вы обнаружили ошибку или неточность в данном уроке, сообщите о ней в комментариях к данному уроку. Это поможет сделать курс лучше.