Як State спрощує великі умовні конструкції (if-else/switch)?
Патерн State (Стан) спрощує великі конструкції if-else і switch,
розносячи різну поведінку по окремих класах,
замість того щоб тримати всі умови і переходи всередині одного методу.
1. Проблема без патерна
Коли об'єкт має декілька станів, його поведінку часто описують через довгі умовні блоки:
class Player {
private String state = "IDLE";
public void handleInput(String input) {
if (state.equals("IDLE")) {
if (input.equals("PRESS")) state = "RUNNING";
} else if (state.equals("RUNNING")) {
if (input.equals("STOP")) state = "IDLE";
else if (input.equals("ATTACK")) state = "ATTACKING";
} else if (state.equals("ATTACKING")) {
if (input.equals("STOP")) state = "IDLE";
}
}
}Проблема:
- Метод розростається до сотень рядків.
- Новий стан → новий
if. - При змінах потрібно лізти в наявний код і ризикувати все зламати.
2. Як працює State
Патерн виносить кожен стан в окремий клас, де зберігається лише логіка, що стосується цього стану.
interface State {
void handleInput(Player context, String input);
}
class IdleState implements State {
public void handleInput(Player context, String input) {
if (input.equals("PRESS")) context.setState(new RunningState());
}
}
class RunningState implements State {
public void handleInput(Player context, String input) {
if (input.equals("STOP")) context.setState(new IdleState());
if (input.equals("ATTACK")) context.setState(new AttackingState());
}
}
class AttackingState implements State {
public void handleInput(Player context, String input) {
if (input.equals("STOP")) context.setState(new IdleState());
}
}
class Player {
private State state = new IdleState();
public void setState(State s) { state = s; }
public void handleInput(String input) { state.handleInput(this, input); }
}Тепер при зміні стану просто додається новий клас,
а не нова гілка в if.
3. Що саме спрощується
Проблема в if-else | Рішення через State |
|---|---|
| Один метод керує всіма станами | Кожен стан інкапсулює свою поведінку |
| Складно додавати нові стани | Додавання нового класу не ламає старі |
Код із вкладеними if погано читається | Плоска структура - 1 клас = 1 стан |
| Зміна логіки ламає інші гілки | Ізоляція змін: стани незалежні |
| Складно тестувати | Можна тестувати кожен стан окремо |
4. Чому це працює
Патерн перетворює поведінку, залежну від стану, на набір взаємозамінних об'єктів, між якими контекст просто перемикається:
context.setState(new AttackingState());Більше не потрібно перевіряти, "у якому стані я зараз" - об'єкт сам знає, що робити у своєму стані.
Висновок
Патерн State прибирає громіздкі умовні блоки, передаючи відповідальність за поведінку об'єктам-станам.
Підсумок:
Замість сотні
if-elseвсередині одного класу - десяток маленьких класів, кожен знає свою справу. Це робить код чистим, розширюваним і легко читабельним.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.