Sobes.tech
Back to questions
Junior — Middle
54

Можете объяснить концепцию паттерна State и как он используется в объектно-ориентированном программировании?

Companies where asked
Ifellow

Answer from AI

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 задает операции, а конкретные состояния реализуют допустимое поведение.

  1. У нового заказа состояние NewState.
  2. Вызов pay() у Order делегируется текущему состоянию.
  3. NewState переводит заказ в PaidState.
  4. После оплаты вызов ship() уже обрабатывает PaidState, которое переводит заказ в ShippedState.
  5. Если вызвать недопустимую операцию, состояние само решает, что делать: запретить действие или вывести сообщение.

Ключевые моменты:

  • State убирает сложные условия по типу if (state == ...).
  • Поведение объекта меняется через замену объекта состояния, а не через разрастание логики в одном классе.
  • Каждый класс состояния отвечает только за свою часть поведения.
  • Паттерн удобен, когда есть четкая конечная логика переходов между состояниями.
  • Часто используется в workflow, обработке заказов, игровых объектах, UI и протоколах.