Шаблон проектирования - Strategy в Java

Cover Image for Шаблон проектирования - Strategy в Java

    Содержание

  • Шаблон проектирования Strategy
  • Преймущества
  • Пример применения
  • Вывод

Шаблон проектирования Strategy.

Шаблон проектирования Strategy — это поведенческий шаблон, который позволяет определить семейство алгоритмов, инкапсулировать каждый из них в виде объекта и сделать их взаимозаменяемыми. Этот шаблон позволяет изменять алгоритмы независимо от клиентов, которые их используют, что упрощает добавление, изменение или удаление алгоритмов, не затрагивая клиентов.

Шаблон Strategy состоит из трех основных компонентов: контекста, интерфейса стратегии и конкретных стратегий.

  1. Контекст: Контекст определяет интересующий клиентов интерфейс и поддерживает ссылку на объект стратегии. Он делегирует работу объекту стратегии, а также может изменять его состояние на основе результатов.

  2. Интерфейс Strategy: Интерфейс стратегии определяет общий интерфейс для всех конкретных стратегий. Обычно он объявляет один или несколько методов, которые контекст может использовать для вызова алгоритма стратегии.

  3. Реализация Strategy: Конкретные стратегии реализуют интерфейс стратегии и предоставляют различные реализации алгоритма стратегии.

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

Шаблон стратегии предлагает несколько преимуществ:

  1. Разделение ответственности: шаблон Strategy отделяет реализацию алгоритма от клиентского кода, упрощая поддержку и модификацию кода.

  2. Гибкость. Шаблон Strategy позволяет добавлять, удалять или изменять алгоритмы во время выполнения, не затрагивая клиентский код.

  3. Повторное использование: шаблон Strategy позволяет повторно использовать алгоритмы в разных контекстах, уменьшая дублирование кода.

  4. Тестируемость: шаблон Strategy упрощает тестирование реализации алгоритма независимо от клиентского кода, повышая тестируемость и снижая риск ошибок.

Рассмотрим пример того, как вы можете использовать шаблон стратегии и шаблон фабрики в Spring Boot для реализации службы обмена валюты. Допустим, у вас есть веб-сервис электронной коммерции, который позволяет клиентам конвертировать валюту. Чтобы реализовать это, вам нужно иметь способ конвертировать валюту в валюту по выбору клиента. Спроектируем модель данных - валюта:

public enum Currency {  
    USD, EURO  
}

Дальше необходимо определить интерфейс сервиса обмена валюты:

public interface CurrencyExchangeService {  
    BigDecimal exchange(BigDecimal amount);  
    Currency getSourceCurrency();  
    Currency getTargetCurrency();  
}

Этот интерфейс определяет метод обмена заданного количества валюты с одной валюты на другую, а также методы получения исходной и целевой валют.

Далее определим фабрику для создания сервисов обмена валюты на основе исходной и целевой валюты:

@Component  
public class CurrencyExchangeServiceFactory {  
    private final Map<CurrencyKey, CurrencyExchangeService> serviceMap = new HashMap<>();  
  
    public CurrencyExchangeServiceFactory(@NonNull final List<CurrencyExchangeService> services) {  
        services.forEach(service -> {  
            CurrencyKey currencies = new CurrencyKey(service.getSourceCurrency(), service.getTargetCurrency());  
            serviceMap.put(currencies, service);  
        });  
    }  
  
    public CurrencyExchangeService getCurrencyExchangeService(@NonNull final Currency sourceCurrency, @NonNull final Currency targetCurrency) {  
        return serviceMap.get(new CurrencyKey(sourceCurrency, targetCurrency));  
    }  
}

где CurrencyKey:

public record CurrencyKey(Currency from, Currency to) {  
}

Эта фабрика берет список служб обмена валюты и создает карту экземпляров служб на основе исходной и целевой валют. Метод getCurrencyExchangeServiceвозвращает экземпляр службы на основе исходной и целевой валют.

Теперь давайте определим некоторые услуги по обмену валюты, используя шаблон стратегии: Пример стратегии конвертации из евро в доллары

@Component  
public class EurToUsdCurrencyExchangeService implements CurrencyExchangeService {  
    private final BigDecimal exchangeRate = BigDecimal.valueOf(1.20);  
  
    @Override  
  public BigDecimal exchange(@NonNull final BigDecimal amount) {  
        return amount.multiply(exchangeRate);  
    }  
  
    @Override  
  public Currency getSourceCurrency() {  
        return EURO;  
    }  
  
    @Override  
  public Currency getTargetCurrency() {  
        return USD;  
    }  
}

Пример стратегии конвертации долларов в евро

@Component  
public class UsdToEurCurrencyExchangeService implements CurrencyExchangeService {  
    private final BigDecimal exchangeRate = BigDecimal.valueOf(0.84);  
  
    @Override  
  public BigDecimal exchange(@NonNull final BigDecimal amount) {  
        return amount.multiply(exchangeRate);  
    }  
  
    @Override  
  public Currency getSourceCurrency() {  
        return USD;  
    }  
  
    @Override  
  public Currency getTargetCurrency() {  
        return EURO;  
    }  
}

Эти сервисы реализуют CurrencyExchangeServiceинтерфейс и предоставляют исходную и целевую валюты, с которыми они работают. Метод exchangeсодержит алгоритм обмена валют.

Наконец, давайте используем фабрику для обмена валют:

public interface CurrencyExchanger {  
    BigDecimal exchange(BigDecimal amount, Currency sourceCurrency, Currency targetCurrency);  
}

@Service  
@RequiredArgsConstructor  
public class CurrencyExchangerImpl implements CurrencyExchanger {  
    private final CurrencyExchangeServiceFactory factory;  
  
    @Override  
  public BigDecimal exchange(@NonNull final BigDecimal amount, @NonNull final Currency sourceCurrency, @NonNull final Currency targetCurrency) {  
        CurrencyExchangeService service = factory.getCurrencyExchangeService(sourceCurrency, targetCurrency);  
        return service.exchange(amount);  
    }  
}

Этот сервис использует фабрику, чтобы получить соответствующую услугу обмена валюты на основе исходной и целевой валют. Затем он вызывает exchangeметод экземпляра службы для обмена валют. Теперь пришло время реализовать веб-сервис по конвертации валют:

@RestController  
@RequestMapping("/api")  
@RequiredArgsConstructor  
public class ExchangerController {  
 
   private final CurrencyExchanger currencyExchanger;  
 
   @GetMapping("/exchange")  
   public ResponseEntity<BigDecimal> exchange(@RequestParam final int value, @RequestParam final Currency from, @RequestParam final Currency to) {  
       return ResponseEntity.ok(currencyExchanger.exchange(BigDecimal.valueOf(value), from, to));  
   }  
 
}

Проверить работоспособность можно так - http://localhost:8080/api/exchange?value=100&from=EURO&to=USD

В целом, шаблон стратегии с Spring — это мощный инструмент, который позволяет вам управлять несколькими алгоритмами или стратегиями в вашем приложении. Это повышает гибкость вашего кода, уменьшая дублирование кода и способствуя повторному использованию кода.

Возникли вопросы по статье, не работает код, хотелось бы больше информации - свяжитесь с нами и мы поможем