Должен ли шаблон стратегии быть без гражданства? - PullRequest
9 голосов
/ 30 мая 2011

Должен ли класс, который является стратегией "банды четырех", быть полностью не имеющим состояния (то есть без полей) или он может содержать неизменяемое состояние (то есть конечные поля)?

Ответы [ 5 ]

17 голосов
/ 30 мая 2011

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

Кроме того, не зависит ли класс от состояния или от состояния не зависит от ключевого слова final в его полях. Примеры:

  • При использовании на объектах final означает только то, что ссылка на объект не может быть изменена. Вы все еще можете изменить содержимое этого объекта, как и его поля. В этом случае ваш класс заполнен, хотя его поле является окончательным.
  • Если поле действительно является константой, то для большинства намерений и целей вы можете считать его не имеющим состояния. Например, вы можете объявить поле private static final, а затем убедиться, что вы ничего не делаете для изменения состояния ссылочного объекта.

РЕДАКТИРОВАТЬ: Давайте попробуем различать параметры самой стратегии и параметров одного конкретного выполнения этой стратегии. Если класс стратегии не имеет состояния, то нет смысла иметь более одного экземпляра этого класса, что делает объект, а не класс, представляет само действие, а выполнение метода представляет одно конкретное выполнение этой стратегии.

Теперь, если у нас есть параметр самой стратегии, то имеет смысл только, чтобы этот параметр имел одинаковое значение для всех исполнений этой стратегии. Таким образом, он может быть помещен в константу, вызов метода, который возвращает константу (если мы не хотим статических вещей), или даже жестко закодирован Как объяснено выше, это может быть реализовано без сохранения состояния.

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

Дополнительное примечание: есть веская причина использовать объекты действий с «наречими», упакованными в своем состоянии, если мы хотим, скажем, иметь какую-то очередь действий с задержкой и расписанием ... Для этого есть шаблон тоже - Команда.

4 голосов
/ 30 мая 2011

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

3 голосов
/ 30 мая 2011

Безгражданство относится к тому факту, что между запусками стратегии не сохраняется никаких данных; т.е. если вы выполняете одну и ту же стратегию дважды, ничто из предыдущего запуска стратегии не будет перенесено. Это выгодно тем, что избавляет вас от необходимости «сбрасывать» реализации вашей Стратегии при необходимости.

Обратите внимание, что в описании реализации шаблона Стратегии они ссылаются на Контекст (@ стр. 317 в моей книге), который содержит данные, которые должна выполнить стратегия. Все «состояние», требуемое реализациями, вероятно, должно идти в этих объектах контекста.

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

Например, если у вас были реализации стратегии для математических операций, есть как минимум 2 способа сделать это. Первым было бы установить arg1 и arg2 (и 3, и 4 ...) для реализаций стратегии при их создании. Затем при выполнении реализация захватит его поля и выполнит операцию. Проблема в том, что если вы снова запустите ту же реализацию, вам придется сбросить все ее поля (или создать новую реализацию).

Второй способ - создать контекст, содержащий все аргументы. Реализации Stategy будут получать значения, которые ему нужны вне контекста. Затем вы можете повторно использовать каждый экземпляр вашей стратегии, просто каждый раз передавая новый контекст. Не беспокойтесь о воссоздании новых экземпляров реализаций и не забудьте сбросить экземпляр реализации. Конечно, вам все равно нужно правильно управлять контекстами.

3 голосов
/ 30 мая 2011

Целью паттерна стратегии является работа с аргументами метода стратегии непосредственно в локальной области действия метода.Сам класс стратегии, конечно, может содержать некоторые поля всякий раз, когда это необходимо, но аргументы метода никоим образом не должны присваиваться этим полям, поскольку он может создавать проблемы безопасности потоков, если объект стратегии используется более одного раза.

1 голос
/ 30 мая 2011

Да, так как в основном это алгоритм выбора.Конкретный алгоритм может иметь состояние, но не выбор.

Кстати, в этой стратегии у нас нет одного класса.Какой конкретный класс вы имеете в виду?В какой роли?

...