Является ли наследование контекста, как показано в примере с утилитой Head First Design Patterns, не относящимся к шаблону стратегии?

10

В Head First Design Patterns он учит шаблону стратегии , используя пример Duck, где различным подклассам Duck может быть назначено определенное поведение во время выполнения. Насколько я понимаю, целью паттерна стратегии является изменение поведения одного объекта во время выполнения, но они используют наследование Duck для изменения поведения различных типов Duck.

Шаблон стратегии

Актуальность?

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

Более простой пример

Могу ли я еще упростить этот пример, просто имея класс Duck (без производных классов)? Затем при реализации одного объекта утки ему могут быть назначены различные варианты поведения, основанные на определенных обстоятельствах, которые не зависят от его собственного типа объекта. Например: изменения FlyBehavior в зависимости от погоды или QuackBehavior изменяются в зависимости от времени суток или от того, насколько голодна утка. Я понимаю, что это решило бы проблему, отличную от той, которая описана в книге, но я ищу подходящий пример паттерна стратегии, к которому можно обратиться.

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

Редактировать:

Мне удалось найти 2 более простых примера шаблонов стратегий, которые более строго придерживаются принципов стратегии без наследования контекста: Hunter.java и solver.py .

Корей Хинтон
источник

Ответы:

7

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

Из Design Patterns: Elements of Reusable OOP вы бы использовали шаблон стратегии для

  • Избегайте взрыва подклассов (из-за сочетания поведения)
  • Если вам нужно поменять поведение во время выполнения

Если бы вы использовали наследование для реализации поведения Quack и Fly, вы бы получили все эти подклассы для представления всех комбинаций поведения.

  • FlyableQuackableDuck
  • FlyableSqeakableDuck
  • FlyableMuteDuck
  • NoFlyQuackableDuck
  • NoFlySqueakableDuck
  • NoFlyMuteDuck

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

Вы также упомянули преимущество во время выполнения, если погода изменила свойство утки Fly, которое может быть заменено объектом NoFly из-за условий.

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

Деспертар
источник
1

Могу ли я еще упростить этот пример, просто имея класс Duck (без производных классов)? Затем при реализации одного объекта утки ему могут быть назначены различные варианты поведения, основанные на определенных обстоятельствах, которые не зависят от его собственного типа объекта.

Безусловно. Для вдохновения загляните в Head First Object-Oriented Analysis and Design . Есть "Гитары Рика", показывающие взрыв подклассов (музыкальных) инструментов . Чтобы исправить это, все это изменяющееся поведение заключено в «спецификационный» класс, соблюдая принцип инкапсуляции того, что меняется .

Абстрактная фабрика - контекстно-ориентированная конструкция

Вот образец . Кстати, обратите внимание, что он использует саму стратегию.

Сосредоточив внимание на концепции, а не на реализации ... У вас может быть «WeatherFactory», которая создает объекты спецификации на основе солнечного или дождливого и т. Д. Условий.

Вы могли бы иметь "фабрики фабрик", чтобы получить возможность создавать эти вещи "NoFlyInFogQuackableMallard". И действительно, это то, что представляет собой шаблон абстрактной фабрики. Так что, возможно, DuckFactory для создания общих типов утки, а затем WeatherFactory для определения поведения тумана в зависимости от типа утки.

radarbob
источник