Вопросы по JS

Паттерн Стратегия

Паттерн Стратегия (Strategy Pattern) — это один из поведенческих паттернов проектирования, который позволяет определять семейство алгоритмов, помещать каждый из них в отдельный класс и обеспечивать их взаимозаменяемость. Этот паттерн позволяет выбирать алгоритм, который будет использоваться, в зависимости от ситуации.

Основные компоненты паттерна

  1. Интерфейс стратегии — определяет общий интерфейс для всех конкретных стратегий.
  2. Конкретные стратегии — реализуют поведение, определенное интерфейсом стратегии.
  3. Контекст — использует стратегии и передает данные для выполнения.

Пример реализации

Разберем пример реализации паттерна Стратегия. Для этого создадим простую программу, которая будет вычислять стоимость заказа в зависимости от выбранного способа доставки (авиа, наземный или морской).

Код

// Интерфейс стратегии
class DeliveryStrategy {
    calculateCost(weight) {
        throw new Error("Метод calculateCost должен быть переопределен");
    }
}

// Конкретные стратегии
class AirDelivery extends DeliveryStrategy {
    calculateCost(weight) {
        return weight * 10; // цена за авиа доставку
    }
}

class GroundDelivery extends DeliveryStrategy {
    calculateCost(weight) {
        return weight * 5; // цена за наземную доставку
    }
}

class SeaDelivery extends DeliveryStrategy {
    calculateCost(weight) {
        return weight * 2; // цена за морскую доставку
    }
}

// Контекст
class Order {
    constructor(weight) {
        this.weight = weight;
        this.deliveryStrategy = null; // начальное значение стратегии
    }
    
    setDeliveryStrategy(strategy) {
        this.deliveryStrategy = strategy;
    }
    
    calculateDeliveryCost() {
        if (!this.deliveryStrategy) {
            throw new Error("Стратегия доставки не задана");
        }
        return this.deliveryStrategy.calculateCost(this.weight);
    }
}

// Пример использования
const order = new Order(15); // Вес посылки 15 кг

// Устанавливаем стратегию
order.setDeliveryStrategy(new AirDelivery());
console.log("Стоимость авиа доставки: $" + order.calculateDeliveryCost());

order.setDeliveryStrategy(new GroundDelivery());
console.log("Стоимость наземной доставки: $" + order.calculateDeliveryCost());

order.setDeliveryStrategy(new SeaDelivery());
console.log("Стоимость морской доставки: $" + order.calculateDeliveryCost());

Объяснение кода

  1. Интерфейс DeliveryStrategy: содержит метод calculateCost, который должен быть реализован в конкретных стратегиях.
  2. Конкретные стратегии: AirDelivery, GroundDelivery и SeaDelivery реализуют метод calculateCost, предоставляя свое собственное поведение для расчета стоимости доставки.
  3. Контекст (Order): хранит вес заказа и позволяет устанавливать выбранную стратегию доставки. Метод calculateDeliveryCost использует установленную стратегию для расчета стоимости.

Преимущества

  • Гибкость: можно легко добавлять новые стратегии без изменения существующего кода.
  • Изолированность кода: каждая стратегия находится в своем собственном классе, что делает код более читаемым и поддерживаемым.
  • Упрощение кода: благодаря использованию паттерна не нужно использовать сложные условные конструкции для выбора алгоритма.

Заключение

Паттерн Стратегия полезен, когда у вас есть несколько алгоритмов для одной и той же задачи и вам нужно выбрать между ними в зависимости от условий. Это делает ваш код более гибким и легким в обслуживании.