Ответ
Паттерны «Состояние» (State) и «Стратегия» (Strategy) имеют схожую структуру (композиция и делегирование), но решают разные задачи.
Паттерн «Состояние»
- Назначение: Позволять объекту менять свое поведение при изменении его внутреннего состояния. Объект будет вести себя как будто он изменил класс.
- Взаимодействие: Конкретные состояния знают друг о друге и могут инициировать переход контекста в другое состояние.
- Акцент: На управлении жизненным циклом и переходами между состояниями объекта (например, заказ:
New->Paid->Shipped).
Пример (Состояние заказа):
interface OrderState {
void cancel(OrderContext context);
void ship(OrderContext context);
}
class PaidState implements OrderState {
public void cancel(OrderContext context) {
// Логика отмены оплаченного заказа
context.setState(new CancelledState()); // Переход в новое состояние
}
public void ship(OrderContext context) {
context.setState(new ShippedState()); // Переход
}
}
// Контекст хранит текущее состояние
class OrderContext {
private OrderState currentState;
public void setState(OrderState state) { this.currentState = state; }
public void cancel() { currentState.cancel(this); } // Делегирование
}
Паттерн «Стратегия»
- Назначение: Определять семейство алгоритмов, инкапсулировать каждый из них и делать их взаимозаменяемыми. Позволяет изменять алгоритм независимо от клиента, который его использует.
- Взаимодействие: Конкретные стратегии не знают друг о друге. Клиент (контекст) явно выбирает, какую стратегию использовать.
- Акцент: На вариативности поведения объекта (например, разные алгоритмы сортировки, способы оплаты).
Пример (Стратегия оплаты):
interface PaymentStrategy {
void pay(double amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(double amount) { /* Обработка карты */ }
}
class PayPalPayment implements PaymentStrategy {
public void pay(double amount) { /* Вызов API PayPal */ }
}
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy; // Клиент выбирает стратегию
}
public void checkout(double amount) {
paymentStrategy.pay(amount); // Делегирование
}
}
Сводка различий
| Критерий | Состояние (State) | Стратегия (Strategy) |
|---|---|---|
| Цель | Управление поведением в зависимости от состояния объекта | Предоставление различных взаимозаменяемых алгоритмов |
| Управление переходами | Внутри самих состояний | Внешнее, со стороны клиента контекста |
| Осведомленность | Состояния знают о других состояниях для переходов | Стратегии независимы и не знают о других |
| Изменение поведения | Автоматическое, как следствие изменения состояния | Явное, по выбору клиента |
Проще говоря: State — это о том, кто вы (и ваше поведение меняется автоматически), а Strategy — о том, что вы делаете (и вы сами выбираете, как это делать).