Поведенческие паттерны
Поведенческие паттерны решают проблемы взаимодействия между объектами и распределения ответственности между ними.
Что такое поведенческие паттерны?
Поведенческие паттерны определяют алгоритмы и способы взаимодействия между объектами. Они помогают организовать код так, чтобы объекты могли эффективно взаимодействовать друг с другом.
Основные паттерны
- Observer (Наблюдатель) — уведомляет объекты об изменениях
- Visitor (Посетитель) — добавляет операции без изменения классов
- Strategy (Стратегия) — выбирает алгоритм во время выполнения
- Command (Команда) — инкапсулирует запросы как объекты
- State (Состояние) — изменяет поведение при изменении состояния
- Template Method (Шаблонный метод) — определяет скелет алгоритма
- Iterator (Итератор) — обходит элементы коллекции
- Mediator (Посредник) — централизует взаимодействие между объектами
- Memento (Хранитель) — сохраняет и восстанавливает состояние
- Chain of Responsibility (Цепочка обязанностей) — передает запросы по цепочке
Подробное описание паттернов
Observer (Наблюдатель)
Создает механизм подписки, позволяющий объектам следить и реагировать на события.
Когда использовать:
- Когда изменение одного объекта требует изменения других объектов
- Когда объекты должны быть слабо связаны
Visitor (Посетитель)
Позволяет добавлять новые операции к объектам, не изменяя их классов.
Когда использовать:
- Когда нужно выполнять операции над объектами разных классов
- Когда операции не должны изменять классы объектов
Strategy (Стратегия)
Определяет семейство алгоритмов и делает их взаимозаменяемыми.
Когда использовать:
- Когда есть несколько способов выполнения задачи
- Когда нужно выбирать алгоритм во время выполнения
Command (Команда)
Превращает запросы в объекты, позволяя передавать их как аргументы.
Когда использовать:
- Когда нужно параметризовать объекты операциями
- Когда нужна поддержка отмены операций
State (Состояние)
Позволяет объектам изменять поведение при изменении внутреннего состояния.
Когда использовать:
- Когда объект ведет себя по-разному в зависимости от состояния
- Когда много условных операторов зависят от состояния
Template Method (Шаблонный метод)
Определяет скелет алгоритма, позволяя подклассам переопределять определенные шаги.
Когда использовать:
- Когда есть несколько классов с похожими алгоритмами
- Когда нужно избежать дублирования кода
Iterator (Итератор)
Позволяет последовательно обходить элементы составного объекта.
Когда использовать:
- Когда нужно обходить сложные структуры данных
- Когда хотите скрыть детали реализации коллекции
Mediator (Посредник)
Позволяет уменьшить связанность множества классов между собой.
Когда использовать:
- Когда много объектов взаимодействуют друг с другом
- Когда объекты тесно связаны и сложно изменять их независимо
Memento (Хранитель)
Позволяет сохранять и восстанавливать предыдущее состояние объекта.
Когда использовать:
- Когда нужно сохранять и восстанавливать состояние объекта
- Когда нужна система отмены/повтора операций
Chain of Responsibility (Цепочка обязанностей)
Позволяет передавать запросы по цепочке обработчиков.
Когда использовать:
- Когда нужно обрабатывать запросы несколькими обработчиками
- Когда порядок обработчиков может изменяться
Примеры использования
Observer
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
Strategy
class Context {
constructor(strategy) {
this.strategy = strategy;
}
executeStrategy(data) {
return this.strategy.execute(data);
}
}
Преимущества
- Улучшают взаимодействие между объектами
- Делают код более гибким и расширяемым
- Помогают организовать сложную логику
- Уменьшают связанность между компонентами
Недостатки
- Могут усложнить архитектуру
- Некоторые паттерны требуют дополнительного кода
- Могут снизить производительность
Поведенческие паттерны — это основа гибкого и расширяемого кода!