Какие паттерны поведения (Behavioral Patterns) вы знаете?

«Какие паттерны поведения (Behavioral Patterns) вы знаете?» — вопрос из категории Паттерны, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Паттерны поведения фокусируются на алгоритмах и распределении ответственности между объектами, упрощая взаимодействие и делая его более гибким.

Ключевые паттерны поведения:

  1. 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);

  2. 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); }
  3. 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));
  4. Chain of Responsibility (Цепочка обязанностей):

    • Суть: Позволяет передавать запрос по цепочке потенциальных обработчиков, пока один из них не обработает его. Используется в middleware, логгерах, обработке событий.
  5. State (Состояние):

    • Суть: Позволяет объекту изменять свое поведение при изменении внутреннего состояния, создавая впечатление, что объект изменил свой класс.
  6. Template Method (Шаблонный метод):

    • Суть: Определяет скелет алгоритма в базовом классе, оставляя реализацию некоторых шагов подклассам.
  7. Iterator (Итератор):

    • Суть: Предоставляет способ последовательного доступа к элементам составного объекта, не раскрывая его внутреннего представления.
  8. Mediator (Посредник):

    • Суть: Централизует сложные взаимодействия между множеством объектов в одном объекте-посреднике, уменьшая связанность компонентов.
  9. Visitor (Посетитель):

    • Суть: Позволяет добавлять новые операции к объектам, не изменяя их классов, путем вынесения логики в отдельные классы-посетители.
  10. Memento (Снимок):

    • Суть: Позволяет сохранять и восстанавливать предыдущее состояние объекта, не раскрывая деталей его реализации.