Можете объяснить концепцию паттерна State и как он используется в объектно-ориентированном программировании?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Паттерн State позволяет объекту менять поведение при изменении внутреннего состояния, не используя большие if/else или switch. Вместо этого состояние выносится в отдельные классы, и объект делегирует им часть логики. Это делает код чище, расширяемее и проще в поддержке.
Определение:
State — это поведенческий паттерн, который позволяет объекту изменять свое поведение в зависимости от внутреннего состояния так, будто класс объекта изменился. Каждое состояние инкапсулируется в отдельный класс, а переходы между состояниями управляются через общий интерфейс.
Пример использования:
Допустим, есть заказ в интернет-магазине: New, Paid, Shipped. Поведение заказа зависит от текущего состояния: нельзя отправить неоплаченный заказ, нельзя оплатить уже отправленный. Вместо цепочки условий удобно вынести каждое состояние в отдельный класс.
interface OrderState {
void pay(Order order);
void ship(Order order);
}
class NewState implements OrderState {
public void pay(Order order) {
order.setState(new PaidState());
System.out.println("Заказ оплачен");
}
public void ship(Order order) {
System.out.println("Нельзя отправить неоплаченный заказ");
}
}
class PaidState implements OrderState {
public void pay(Order order) {
System.out.println("Заказ уже оплачен");
}
public void ship(Order order) {
order.setState(new ShippedState());
System.out.println("Заказ отправлен");
}
}
class ShippedState implements OrderState {
public void pay(Order order) {
System.out.println("Заказ уже отправлен, оплата невозможна");
}
public void ship(Order order) {
System.out.println("Заказ уже отправлен");
}
}
class Order {
private OrderState state = new NewState();
public void setState(OrderState state) {
this.state = state;
}
public void pay() {
state.pay(this);
}
public void ship() {
state.ship(this);
}
}
Пояснение кода:
Здесь Order — контекст, который хранит текущее состояние. Интерфейс OrderState задает операции, а конкретные состояния реализуют допустимое поведение.
- У нового заказа состояние
NewState. - Вызов
pay()уOrderделегируется текущему состоянию. NewStateпереводит заказ вPaidState.- После оплаты вызов
ship()уже обрабатываетPaidState, которое переводит заказ вShippedState. - Если вызвать недопустимую операцию, состояние само решает, что делать: запретить действие или вывести сообщение.
Ключевые моменты:
- State убирает сложные условия по типу
if (state == ...). - Поведение объекта меняется через замену объекта состояния, а не через разрастание логики в одном классе.
- Каждый класс состояния отвечает только за свою часть поведения.
- Паттерн удобен, когда есть четкая конечная логика переходов между состояниями.
- Часто используется в workflow, обработке заказов, игровых объектах, UI и протоколах.