Javenue logo

Javenue

Программирование на Java

Информационные технологии

Паттерн Strategy на Java - Стратегия

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

Вот ряд преимуществ данного паттерна:

  • позволяет выбирать модель поведения объекта динамически;
  • упрощает процесс добавления новых стратегий;
  • является альтернативой наследованию;
  • избавляет от множества условий (if, case);
  • делает еще много всего.

Если вам понятно, что значит каждый из этих пунктов (особенно 5-ый), переходите сразу к примеру на Java. А мы пока рассмотрим эти пункты немного подробнее.

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

Для выбора модели поведения часто используют наследование. Имея некоторый объект, мы создаем новый экземпляр подкласса этого объекта и присваиваем его самому объекту. При использовании паттерна Startegy, достаточно переключится на интересующую нас стратегию.

Если поведение объекта описывается несколькими методами, паттерн Strategy уменьшит кол-во условий в коде программы. Условный оператор понадобится нам не более одного раза для выбора определенной стратегии.

Использовать паттерн Strategy на практике можно, например, при выборе алгоритма шифрования:

public interface Algorithm {
  String crypt(String text, String key);
}

public class DESAlgorithm implements Algorithm {
  public String crypt(String text, String key) {
    String cryptedString = null;
    // тело алгоритма
    return cryptedString;
  }
}

public class RSAAlgorythm implements Algorythm {
  public String crypt(String text, String key) {
    String cryptedString = null;
    // тело алгоритма
    return cryptedString;
  }
}

public class Encryption {
  private Algorithm algorithm;

  public Encryption(Algorithm algorithm) {
    this.algorithm = algorithm;
  }

  public setAlgorithm(Algorithm algorithm) {
    this.algorithm = algorithm;
  }

  public crypt(String text, String key) {
    return algorithm.crypt(text, key);
  }
}

public class Test {
  public static void main(String[] args) {
    String key = “key”;
    String text = “text”;
    int alg = 1;
    Encryption encryption = new Encryption(new DESAlgorithm());
    String cryptedText = encryption.crypt(text, key);
  }
}

Далее, если нам в некотором участке кода понадобится поменять стратегию криптования, допустим по какому-то условию, можно сделать следующее:

  ...
  boolean needToChange = true;
  ...
  if (needToChange)
    encryption.setAlgorithm(new RSAAlgorithm());
  ...

Ну вот и все.

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

Жду ваших вопросов и комментариев.



Комментариев: 5

  Выйти

  * для публикации комментариев нужно  

Slava:

Ужасно! В настоящем ООП не должно быть if-в тем более case-в! В примере нет никакого паттерна стратегия! Жесть, а не пример.

c0nst:

Если зарегистрировано более одного алгоритма, как выбрать конкретный из них в runtime? Выбор основывается на сравнении, соответственно и на условии.

Есть конечно другой вариант. Пример - несколько приложений исползьзуют одно и то же API. Каждое приложение может иметь свою стратегию построения путей к файлам на файловой системе. Серверное приложение делает это через бины (читает из БД); GUI приложение - через свои настройки; тестовый фреймворк - на основании входящих данных. В этом случае выбор стратегии сделан заранее.

Alexander:

а почему собственно “В настоящем ООП не должно быть if-в тем более case-в” ? интересует конкретный ответ.

Иванов Иван:

Можно все алгоритмы засунуть в set и от туда уже тянуть их

Konstantin Chapiuk:

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