Ответ
Паттерны поведения фокусируются на алгоритмах и распределении ответственности между объектами, упрощая взаимодействие и делая его более гибким.
Ключевые паттерны поведения:
-
Strategy(Стратегия):- Суть: Инкапсулирует семейство алгоритмов, делая их взаимозаменяемыми. Позволяет изменять алгоритм независимо от клиента, который его использует.
- Пример (Сортировка):
interface SortStrategy { void sort(List<Integer> data); } class QuickSort implements SortStrategy { /* ... */ } class MergeSort implements SortStrategy { /* ... */ }
class Sorter { private SortStrategy strategy; public Sorter(SortStrategy strategy) { this.strategy = strategy; } public void performSort(List
data) { strategy.sort(data); } } // Использование: Sorter sorter = new Sorter(new QuickSort()); sorter.performSort(myList); -
Observer/Publisher-Subscriber(Наблюдатель):- Суть: Определяет зависимость «один-ко-многим» между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются автоматически.
-
Пример (Система уведомлений):
// Издатель (Subject) class NewsAgency { private List<Subscriber> subscribers = new ArrayList<>(); private String news; public void addSubscriber(Subscriber s) { subscribers.add(s); } public void setNews(String news) { this.news = news; notifySubscribers(); // Рассылка уведомлений } private void notifySubscribers() { for (Subscriber s : subscribers) s.update(this.news); } } // Подписчик (Observer) interface Subscriber { void update(String news); }
-
Command(Команда):- Суть: Инкапсулирует запрос как объект, позволяя параметризовать клиентов различными запросами, ставить их в очередь или поддерживать отмену операций.
- Пример (Редактор):
interface Command { void execute(); void undo(); } class CopyCommand implements Command { private Editor editor; public CopyCommand(Editor editor) { this.editor = editor; } @Override public void execute() { editor.copySelection(); } @Override public void undo() { /* Логика отмены копирования */ } } // Кнопка в UI не знает деталей, она просто выполняет команду button.setCommand(new CopyCommand(activeEditor));
-
Chain of Responsibility(Цепочка обязанностей):- Суть: Позволяет передавать запрос по цепочке потенциальных обработчиков, пока один из них не обработает его. Используется в middleware, логгерах, обработке событий.
-
State(Состояние):- Суть: Позволяет объекту изменять свое поведение при изменении внутреннего состояния, создавая впечатление, что объект изменил свой класс.
-
Template Method(Шаблонный метод):- Суть: Определяет скелет алгоритма в базовом классе, оставляя реализацию некоторых шагов подклассам.
-
Iterator(Итератор):- Суть: Предоставляет способ последовательного доступа к элементам составного объекта, не раскрывая его внутреннего представления.
-
Mediator(Посредник):- Суть: Централизует сложные взаимодействия между множеством объектов в одном объекте-посреднике, уменьшая связанность компонентов.
-
Visitor(Посетитель):- Суть: Позволяет добавлять новые операции к объектам, не изменяя их классов, путем вынесения логики в отдельные классы-посетители.
-
Memento(Снимок):- Суть: Позволяет сохранять и восстанавливать предыдущее состояние объекта, не раскрывая деталей его реализации.
Ответ 18+ 🔞
Ну, паттерны поведения — это как раз про то, кто за какую поебень в системе отвечает и как они друг с другом общаются, чтобы не получилось говнисто и запутанно. Смотри, вот тебе раскладка, как в жизни.
Стратегия (Strategy) Вот представь: тебе надо отсортировать список. Можно впендюрить быструю сортировку, можно слиянием, а можно пузырьком, если ты совсем ебанутый. Так вот, стратегия — это когда ты выносишь весь этот алгоритм в отдельную хуйню, и потом подсовываешь её основному объекту. Он нихуя не знает про детали, просто тыкает в неё данными.
interface SortStrategy {
void sort(List<Integer> data);
}
class QuickSort implements SortStrategy { /* ... */ }
class MergeSort implements SortStrategy { /* ... */ }
class Sorter {
private SortStrategy strategy;
public Sorter(SortStrategy strategy) { this.strategy = strategy; }
public void performSort(List<Integer> data) { strategy.sort(data); }
}
// Использование:
Sorter sorter = new Sorter(new QuickSort());
sorter.performSort(myList);
Видишь? Sorterу похуй, что там внутри. Сегодня QuickSort, завтра MergeSort — поменял объект стратегии и всё, ни одной строчки в основном коде не трогал. Красота, блядь.
Наблюдатель (Observer) Это когда одна штука (издатель) орет на всю деревню, что у неё что-то случилось, а кучка других штук (подписчиков) эту дичь ловит и реагирует. Как паблик в телеге: кинул пост — всем прилетело уведомление.
// Издатель (Subject)
class NewsAgency {
private List<Subscriber> subscribers = new ArrayList<>();
private String news;
public void addSubscriber(Subscriber s) { subscribers.add(s); }
public void setNews(String news) {
this.news = news;
notifySubscribers(); // Рассылка уведомлений
}
private void notifySubscribers() {
for (Subscriber s : subscribers) s.update(this.news);
}
}
// Подписчик (Observer)
interface Subscriber { void update(String news); }
Главное — издатель не парится, кто там его слушает. Подписался — получай, отписался — иди нахуй. Связанность — ноль ебать.
Команда (Command) Суть в том, чтобы завернуть какое-то действие в отдельный объект. Типа, «скопировать текст», «вставить», «сохранить». Потом эту команду можно передать куда угодно: кнопке на интерфейсе, горячей клавише, или даже в очередь на выполнение. А ещё — отмену сделать, ёпта!
interface Command {
void execute();
void undo();
}
class CopyCommand implements Command {
private Editor editor;
public CopyCommand(Editor editor) { this.editor = editor; }
@Override
public void execute() { editor.copySelection(); }
@Override
public void undo() { /* Логика отмены копирования */ }
}
// Кнопка в UI не знает деталей, она просто выполняет команду
button.setCommand(new CopyCommand(activeEditor));
Кнопка — тупая, она просто тыкает в команду execute(). А что там внутри — её не ебёт. Хоть копируй, хоть мир в труху стирай.
Цепочка обязанностей (Chain of Responsibility) Представь, что у тебя запрос, как мячик, и он летит по цепочке обезьян. Каждая обезьяна смотрит: «А, это моё?» Если нет — передаёт следующей. Если да — обрабатывает и нахуй отправляет. Так работают, например, фильтры в вебе или логгеры, где каждый уровень решает, писать ему в консоль или нет.
Состояние (State) Объект, который меняет своё поведение в зависимости от того, в каком он состоянии. Как твой друг, который в трезвом виде — философ, а как нажрётся — начинает про политику орать. В коде это выглядит так: у объекта есть ссылка на объект-состояние, и все методы он просто делегирует ему. Сменил состояние — и всё, объект будто другим стал.
Шаблонный метод (Template Method) Это когда в базовом классе прописан скелет алгоритма, но некоторые шаги оставлены абстрактными — пусть дети сами решают, как их делать. Типа, рецепт борща: «свари бульон, добавь овощи, повари ещё». А какие овощи и в каком порядке — это уже твои проблемы, наследничек.
Итератор (Iterator) Даёт возможность пройтись по коллекции, не вскрывая её кишки. Неважно, что внутри — массив, список или дерево. Просто давай следующий элемент, пока они не кончатся. Стандартная хуйня в любом языке, без неё никуда.
Посредник (Mediator) Когда у тебя куча объектов тупо орут друг на друга, получается пиздец и каша. Посредник — это такой отдельный мудак, через которого все общаются. Вместо того чтобы знать друг о друге, объекты знают только посредника. Он получает сообщение и решает, кому его переслать. Связанность падает, но посредник иногда превращается в бога, которого нихуя не перепишешь.
Посетитель (Visitor) Позволяет добавлять новые операции к целой кучке классов, не лезя в них самих. Создаёшь класс-посетитель, который умеет работать с каждым типом объекта, и потом просто «посещаешь» эти объекты, вызывая у них нужный метод. Мощно, но иногда код выглядит так, будто его писал не совсем здоровый человек.
Снимок (Memento)
Нужен, чтобы сохранять состояние объекта и потом, если что, откатываться назад. Как Ctrl+Z в том же редакторе. Объект создаёт снимок своего состояния (не раскрывая всех деталей, конечно), отдаёт его хранителю, а потом может этот снимок забрать и восстановиться. Главное — чтобы сам объект умел себя сохранять и восстанавливать, а остальным это было похуй.
Вот и вся магия. Выбирай, что подходит, и не усложняй там, где можно проще, а то наговнокодишь — потом сам разбираться будешь, как в джунглях.