Назад к вопросам
Middle
81
questionbank
Каковы отличия между шаблонами проектирования ООП 'Стратегия' и 'Состояние'?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Ключевое отличие в назначении и поведении:
- Стратегия (Strategy): Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Позволяет клиенту независимо изменять алгоритм, который используется. Цель — выбор поведения объекта на основе выбранного алгоритма. Состояние объекта не является определяющим фактором для выбора стратегии.
- Состояние (State): Позволяет объекту изменять своё поведение в зависимости от своего внутреннего состояния. На каждом шаге выполнения объект может иметь разное состояние, и на этом основе он меняет свою стратегию поведения. Цель — управление поведением объекта на основе его текущего состояния.
Сравнительная таблица:
| Характеристика | Стратегия (Strategy) | Состояние (State) |
|---|---|---|
| Назначение | Выбор алгоритма поведения. | Изменение поведения объекта в зависимости от состояния. |
| Изменение | Клиент явно выбирает и устанавливает стратегию. | Объект сам переходит между состояниями, меняя поведение. |
| Отношения | Слабая связь между контекстом и конкретной стратегией. | Сильная связь между контекстом и состоянием. |
| Фокус | Алгоритм, используемый объектом. | Состояние объекта, которое определяет его поведение. |
| Переходы | Переключение стратегии происходит явно. | Переключение состояний происходит в ответ на события. |
| Пример | Различные алгоритмы сортировки. | Состояния светофора (красный, желтый, зеленый). |
// Пример Стратегии
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
// Логика оплаты кредитной картой
System.out.println("Paid " + amount + " using Credit Card.");
}
}
class PaypalPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
// Логика оплаты через PayPal
System.out.println("Paid " + amount + " using Paypal.");
}
}
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
if (this.paymentStrategy == null) {
throw new IllegalStateException("Payment strategy not set!"); // Проверка на null
}
this.paymentStrategy.pay(amount);
}
}
// Пример Состояния
interface VendingMachineState {
void selectItem(VendingMachine machine);
void insertMoney(VendingMachine machine);
void dispenseItem(VendingMachine machine);
}
class NoMoneyState implements VendingMachineState {
@Override
public void selectItem(VendingMachine machine) {
System.out.println("Please insert money first.");
}
@Override
public void insertMoney(VendingMachine machine) {
System.out.println("Money inserted. Moving to HasMoneyState.");
machine.setState(new HasMoneyState());
}
@Override
public void dispenseItem(VendingMachine machine) {
System.out.println("Cannot dispense item, no money.");
}
}
class HasMoneyState implements VendingMachineState {
@Override
public void selectItem(VendingMachine machine) {
System.out.println("Item selected.");
machine.setState(new ItemSelectedState()); // Переход в следующее состояние
}
@Override
public void insertMoney(VendingMachine machine) {
System.out.println("Money already inserted.");
}
@Override
public void dispenseItem(VendingMachine machine) {
System.out.println("Cannot dispense item, item not selected.");
}
}
class ItemSelectedState implements VendingMachineState {
@Override
public void selectItem(VendingMachine machine) {
System.out.println("Item already selected.");
}
@Override
public void insertMoney(VendingMachine machine) {
System.out.println("Money already inserted.");
}
@Override
public void dispenseItem(VendingMachine machine) {
System.out.println("Dispensing item.");
machine.setState(new NoMoneyState()); // Возврат в начальное состояние
}
}
class VendingMachine {
private VendingMachineState currentState;
public VendingMachine() {
this.currentState = new NoMoneyState();
}
public void setState(VendingMachineState state) {
this.currentState = state;
}
public void selectItem() {
this.currentState.selectItem(this);
}
public void insertMoney() {
this.currentState.insertMoney(this);
}
public void dispenseItem() {
this.currentState.dispenseItem(this);
}
}