1. Что такое паттерн Mediator
Паттерн Mediator - это поведенческий паттерн проектирования, который снижает прямые зависимости между объектами, перенося их взаимодействие на объект посредник. В паттерне Mediator объекты больше не общаются непосредственно друг с другом, а через объект посредника.
2. Характеристики и преимущества паттерна Mediator
Характеристики и преимущества паттерна Mediator следующие:
- Снижает прямую связанность между объектами, снижая сложность системы.
- Упрощает коммуникацию между объектами с помощью объекта-посредника, который управляет их взаимодействием.
- Централизует контроль взаимодействия между объектами, облегчая расширение и обслуживание.
3. Реальные примеры паттерна Mediator
Паттерн Mediator имеет множество приложений в реальной жизни. Например, в системе планирования аэропорта диспетчер выступает в роли посредника, в то время как различные модули, такие как самолеты и наземное движение, являются классами коллег, которые общаются и координируются через диспетчера.
4. Реализация паттерна Mediator в Golang
4.1 Введение в UML-диаграмму классов
Ниже приведена UML-диаграмма классов для паттерна Mediator в Golang:
4.2 Введение в пример
В этом примере мы реализуем простое приложение чата, используя паттерн Mediator для управления коммуникацией между разными пользователями.
4.3 Шаг 1 реализации: Определение интерфейса Mediator и конкретного посредника
Сначала мы определяем интерфейс посредника и класс конкретного посредника:
type Mediator interface {
registerColleague(colleague Colleague)
sendMessage(message string, colleague Colleague)
}
type ConcreteMediator struct {
colleagues map[string]Colleague
}
func (m *ConcreteMediator) registerColleague(colleague Colleague) {
m.colleagues[colleague.getName()] = colleague
}
func (m *ConcreteMediator) sendMessage(message string, colleague Colleague) {
for _, c := range m.colleagues {
if c != colleague {
c.receiveMessage(message)
}
}
}
4.4 Шаг 2 реализации: Определение интерфейса Colleague и конкретных коллег
Затем мы определяем интерфейс коллеги и классы конкретных коллег:
type Colleague interface {
receiveMessage(message string)
sendMessage(message string)
getName() string
}
type ConcreteColleagueA struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueA) receiveMessage(message string) {
fmt.Printf("%s received message: %s\n", c.name, message)
}
func (c *ConcreteColleagueA) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueA) getName() string {
return c.name
}
type ConcreteColleagueB struct {
mediator Mediator
name string
}
func (c *ConcreteColleagueB) receiveMessage(message string) {
fmt.Printf("%s received message: %s\n", c.name, message)
}
func (c *ConcreteColleagueB) sendMessage(message string) {
c.mediator.sendMessage(message, c)
}
func (c *ConcreteColleagueB) getName() string {
return c.name
}
4.5 Шаг 3 реализации: Управление коллегами в посреднике
В классе конкретного посредника необходимо реализовать метод registerColleague
и метод sendMessage
для управления коммуникацией между классами коллег:
func main() {
mediator := &ConcreteMediator{
colleagues: make(map[string]Colleague),
}
colleagueA := &ConcreteColleagueA{
mediator: mediator,
name: "Colleague A",
}
colleagueB := &ConcreteColleagueB{
mediator: mediator,
name: "Colleague B",
}
mediator.registerColleague(colleagueA)
mediator.registerColleague(colleagueB)
colleagueA.sendMessage("Hello, World!")
colleagueB.sendMessage("Hi, there!")
}
В функции main
создается конкретный объект посредника и два конкретных объекта коллег, затем регистрируются объекты коллег через объект посредника и выполняется тестирование коммуникации.