Skip to main content

Що робить патерн State і коли він корисний?

Патерн State (Стан) використовується для того, щоб змінювати поведінку об'єкта при зміні його внутрішнього стану, не створюючи громіздких конструкцій if-else чи switch.


1. Суть ідеї

Замість того щоб об'єкт сам вирішував, що робити залежно від стану, його поточний стан представлено окремим об'єктом, який знає, як поводитися в даному контексті.

Простіше кажучи: об'єкт "делегує" свою поведінку поточному стану. Коли стан змінюється - змінюється і поведінка.


2. Основна структура

  • Context (Контекст) - об'єкт, поведінка якого залежить від стану. Зберігає посилання на поточний об'єкт-стан.
  • State (Інтерфейс стану) - визначає загальний інтерфейс для всіх можливих станів.
  • ConcreteState (Конкретні стани) - реалізують поведінку для конкретного стану і можуть перемикати контекст на інший.

3. Приклад (Java)

Приклад: банкомат, який поводиться по-різному залежно від стану.

java
// Інтерфейс стану interface ATMState { void insertCard(ATM atm); void withdrawCash(ATM atm, int amount); } // Конкретні стани class NoCard implements ATMState { public void insertCard(ATM atm) { System.out.println("Картку вставлено"); atm.setState(new HasCard()); } public void withdrawCash(ATM atm, int amount) { System.out.println("Немає картки - операція неможлива"); } } class HasCard implements ATMState { public void insertCard(ATM atm) { System.out.println("Картку вже вставлено"); } public void withdrawCash(ATM atm, int amount) { System.out.println("Видано: " + amount); atm.setState(new NoCard()); } } // Контекст class ATM { private ATMState state = new NoCard(); public void setState(ATMState state) { this.state = state; } public void insertCard() { state.insertCard(this); } public void withdrawCash(int amount) { state.withdrawCash(this, amount); } }

Використання:

java
ATM atm = new ATM(); atm.withdrawCash(100); // Немає картки - операція неможлива atm.insertCard(); // Картку вставлено atm.withdrawCash(100); // Видано: 100

4. Коли корисний

1. Коли об'єкт має декілька чітко визначених станів,

і його поведінка повинна змінюватися залежно від стану.

Приклад: банкомат (з карткою / без картки), гра (гравець живий / мертвий), документ (чернетка / опубліковано).

2. Коли код з умовними операторами став важко підтримувати.

Якщо в методах постійно зустрічається:

java
if (state == OPEN) { ... } else if (state == CLOSED) { ... }
  • State замінює це об'єктами станів, роблячи код чистішим і масштабованішим.

3. Коли переходи між станами відбуваються динамічно,

і ними потрібно керувати зсередини самих станів.

Наприклад, при успішній авторизації стан "Гість" сам переводить користувача у стан "Авторизований".


5. Переваги

  • Усуває громіздкі блоки if-else.
  • Делегує відповідальність за поведінку станам - код простіше розширювати.
  • Поведінку можна змінювати на льоту, підміняючи об'єкт стану.
  • Полегшує додавання нових станів без зміни контексту.

6. Недоліки

  • Збільшує кількість класів (кожен стан - окремий клас).
  • При надто простих сценаріях може бути надлишковим.

Висновок

Патерн State робить поведінку об'єкта динамічною і чистою, дозволяючи змінювати її "зсередини" без громіздких умов.

Підсумок:

State - це спосіб навчити об'єкт поводитися по-різному залежно від стану, роблячи код розширюваним, читабельним і реактивним, особливо там, де раніше був суцільний if-else.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.