Подтвердить что ты не робот

Полиморфизм против стратегии

В чем разница между шаблоном Strategy и Polymorphism в Java?

Я смущен тем, что все, что достигается с помощью шаблона стратегии, в принципе возможно благодаря полиморфизму. Исправьте меня, если я ошибаюсь в этом отношении.

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

4b9b3361

Ответ 1

Для меня ссылка из статьи CKing и пример в Википедии достаточно ясны, но я постараюсь дать вы новый пример. По их словам, Strategy Pattern в основном способ изменить поведение алгоритма во время выполнения. Конечно, вы можете достичь этого по-разному (например, сохранить значение и использовать коммутационный футляр, но это будет не так хорошо, как шаблон стратегии).

Предположим, вы разрабатываете пошаговую стратегическую игру с двумя типами Units: пехотной и Tank (подклассы Unit), Ваш ландшафт может быть Равнины, Железная дорога или Леса.

class Unit{
    MovementStrategy ms;      
    final int baseMovement;
    int x,y;

    public Unit(int baseMovement){
        this.baseMovement = baseMovement;
    }

    abstract void fire();

    void moveForward(){
        x = x + ms.getHexagonsToMove(baseMovement);
    }

    void setMovementStrategy(MovementStrategy ms){
        this.ms = ms;
    }
}

Любой подкласс подразделения должен реализовать метод fire(), потому что он будет совершенно другим для них. (Танковые выстрелы тяжелого дальнего раунда, а пехота - несколько коротких световых пулей). В этом примере мы используем обычный полиморфизм/наследование, поскольку метод fire() будет действительно другим для любой единицы, а он не изменится во время игры.

class Infantry extends Unit{
    public Infantry(){
        super(2);
    }

    void fire(){
        //whatever
    }
}

class Tank extends Unit{
    public Tank(){
        super(5);
    }

    void fire(){
        //whatever
    }
}

Единицы также могут перемещаться и иметь поле baseMovement, которое содержит количество шестиугольников, на которые он может ходить. Мы разрабатываем стратегическую игру, а не симуляцию реального мира, поэтому нам все равно, как они двигаются, мы просто хотим добавить значение в свои координаты (в моем примере я использую только координату X, чтобы получить более простой код). Если бы все ландшафты были одинаковыми, нам не нужен какой-либо объект стратегии... но нам нужно изменить поведение метода move() во время выполнения!

Итак, мы реализуем другой класс MovementStrategy для каждого из наших видов Terrain, и мы программируем нашу игру, чтобы вызвать setMovementStrategy() для любой единицы, которая перемещается по каждому шестиугольнику. И нам даже не нужно писать что-либо еще в наших подклассах Unit.

interface MovementStrategy{
    public int getHexagonsToMove(int base);
}

class PlainMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base;
    }
}

class RailroadMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base*3;
    }
}

class ForestMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return (int)(base/2);
    }
}   

Теперь, когда любой Unit перемещается внутри Лес, мы вызываем

unit.setMovementStrategy(new ForestMovementStrategy());

И как только он переходит к Plain, мы делаем:

unit.setMovementStrategy(new PlainMovementStrategy());

Теперь мы можем изменить, как далеко наши подразделения двигаются в зависимости от ландшафта, и нам не нужно переписывать ни один из подклассов.

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

Ответ 2

Я смущен тем, что все, что достигается с помощью шаблона стратегии, в принципе возможно благодаря полиморфизму.

Вы не можете управлять автомобилем без рулевого колеса. Это не означает, что рулевое колесо - это автомобиль. Аналогично, шаблон стратегии опирается на полиморфизм, но это не означает, что они - одно и то же.

Цель шаблона Стратегии - способствовать использованию композиции (has-a) над наследованием (is-a). Вместо того, чтобы ваш класс наследует поведение суперкласса, вы определяете поведение в отдельном классе, а ваш класс имеет ссылку на него.

В качестве примера рассмотрим этот ответ, который хорошо справляется.

Ответ 3

Полиморфизм против шаблона стратегии с примерами ядра Java

  • Основное отличие: Полиморфизм - это концепция языка программирования, а Стратегия - это поведенческий шаблон дизайна GoF.

  • Полиморфизм - это предоставление единого интерфейса объектам разных типов.
    Пример: Рулевое колесо (т.е. интерфейс) одинаково независимо от того, какой тип фактического рулевого механизма используется. То есть, рулевое колесо работает одинаково, имеет ли ваш автомобиль ручное рулевое управление, рулевое управление с усилителем или рулевое управление с зубчатой ​​рейкой. Поэтому, как только вы знаете, как управлять рулевым колесом, вы можете управлять любым типом автомобиля.

  • При программировании Полиморфизм реализован двумя способами:

    • Полиморфизм раннего связывания/статического/компиляционного времени (например, перегрузка функции)
    • Полиморфизм позднего связывания/динамического/рабочего времени (например, переопределение функции)
  • A Шаблон стратегии определяет набор алгоритмов, которые можно использовать взаимозаменяемо.

    • Шаблон стратегии - это динамический шаблон (как вы хотите запускать поведение в программном обеспечении?).
    • Пример ядра java: java.util.Comparator#compare(), выполняемый среди других Collections#sort().

    • Режимы транспорта аналогичны шаблону разработки стратегии. Мы используем автомобиль, велосипед, автобус, локальный поезд и т.д. Различные стратегии, чтобы идти в офис изо дня в день.

Ответ 4

Q: В чем разница между шаблоном стратегии и полиморфизмом в Java?

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

Полиморфизм - это гораздо более широкое понятие в программировании, и да шаблон стратегии в Java использует форму полиморфизма, каталогизированную как полиморфизм включения, чтобы выполнить но это ни в коем случае не единственный тип полиморфизма, который существует, и это единственный способ реализовать стратегический паттерн, как я продемонстрирую в ближайшее время.

Также полиморфизм не является тем, что существует только в Java или в объектно-ориентированных языках программирования. Различные формы полиморфизма существуют во всех парадигмах программирования, а не во всех языках, которые вы вынуждены использовать для полиморфизма для реализации шаблона стратегии (например, функциональных языков).

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

В идеале это покажет вам, что полиморфизм - это более крупная концепция, выходящая за рамки объектно-ориентированного программирования и даже за пределами наследования и подтипирования.

Q: Я смущен тем, что все, что достигается с помощью шаблона стратегии, в принципе возможны полиморфизмом. Исправьте меня, если я ошибаюсь в этом что касается.

Итак, для меня единственное отношение между этими двумя понятиями состоит в том, что, во-первых, шаблон стратегии использует силу полиморфизма, доступного на языках, таких как Java, для реализации его намерения, а во-вторых, что полиморфизм можно рассматривать как образец.

Например, рассмотрите эту цитату из книги GoF:

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

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

В своей книге "Шаблоны дизайна элемента" Джейсон Мак Смит комментирует цитату GoF выше:

Образцы - это понятия, не зависящие от языка; они принимают форму и становятся конкретных решений при их реализации в рамках конкретного язык с заданным набором языковых функций и конструкций [...] Это означает, что немного странно говорить о "дизайне Java" шаблон "," шаблоны проектирования С++ "," шаблон дизайна Websphere "и так далее, хотя мы все это делаем. Это слегка ленивая форма сокращения что мы действительно имеем в виду, или мне нужно: разработать шаблоны, реализованные в Java, С++, WebSphere и т.д., Независимо от языка или API.

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

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

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

Как обсуждалось выше, в Java мы, вероятно, вынуждены использовать полиморфизм включения для реализации шаблона стратегии, но, как объяснялось выше, шаблоны не являются тем, что принадлежит определенному языку, поэтому, если мы думаем о шаблоне стратегии как концепция, живущая вне границ любого языка, тогда вы легко увидите, что другие языки реализуют это по-разному.

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

function readFile(path: String, decrypt: string -> string) {
    return decrypt(loadFromDisk(path));
}

И этот аргумент decrypt - это функция, которая служит цели шаблона стратегии, она инкапсулирует взаимозаменяемый алгоритм.

Теперь вы можете сделать

readFile("customers.txt", aes)
readFile("finance.txt", blowfish)

Где aes и blowfish - стратегии функции дешифрования.

Существуют десятки языков, которые работают так: SML, Haskell, JavaScript и т.д.

Ответ 5

Если вы устанавливаете аналогию, где:

  • В одном случае у вас есть несколько переопределяемых методов;
  • в другом случае у вас есть интерфейс Strategy с несколькими реализациями,

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

Ответ 6

Прежде всего. Полиморфизм может означать две разные вещи. Чаще всего полиморфизм относится к полиморфному типу. Однако вы просите шаблон.

Полиморфный код может меняться каждый раз, когда он работает, а функция кода остается неизменной. Простым примером является 1 + 3 = 4 вместо 5-1 = 4. Оба достигают того же результата, используя другой код. Это полезно для кода, который не хочет распознаваться компьютерными вирусами или криптографическим кодом.

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

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

Ответ 7

Полиморфизм - это принцип, а стратегия - шаблон проектирования

Из документации oracle страница

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

Полиморфизм может быть достигнут во время компиляции (перегрузка метода) и время выполнения (переопределение метода).

Strategy_pattern

  • Определяет семейство алгоритмов,
  • Инкапсулирует каждый алгоритм и
  • Делает алгоритмы взаимозаменяемыми внутри этого семейства.

Стратегия может использовать принцип полиморфизма во время выполнения для достижения желаемой функциональности.

В шаблоне стратегии был еще один компонент, называемый Context в его диаграмме URL. См. Ниже сообщения SE:

Реальный мир Пример шаблона стратегии

Имеет ли этот шаблон стратегии Java избыточный класс Context?

Несколько полезных статей:

strategy с помощью sourcemaking

Ответ 8

Рассмотрим это

У нас есть животные и объект шаблона стратегии, чтобы описать, как они перемещаются... например

покупать/плавать/прогулка

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

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

Ответ 9

Одним из определений для полиморфизма является предоставление единого интерфейса для объектов разных типов.

С учетом этого у вас есть "птичий" интерфейс, и все ваши классы птиц должны реализовать метод "laysEggs()", ну, а не biggie, который работает. И поскольку вы продолжаете кодировать свою "программу райских птиц", вы теперь добавляете "fly()" и понимаете, что перегрузка и переопределение для пингвинов и киви не нужны, так как в реальной жизни они не могут летать, но вы все равно должны реализовать этот метод. Это может стать утомительным и бессмысленным, поскольку вы столкнулись с Страусом и другими, которые не могут летать. И даже самое худшее при добавлении метода "плавать()", потому что еще меньше птиц могут плавать. Как вы уже знаете, шаблон стратегии решает эту проблему.

В терминах хромоты вы можете думать о полиморфизме как о конгломерате практики, в то время как шаблон стратегии - лучшая практика для конкретного случая. Пример: шаблон стратегии должен использоваться, когда поведение алгоритма должно быть выбрано в Runtime (с помощью взаимозаменяемых алгоритмов). И хотя это верно, что все, что достигается с помощью шаблона стратегии, в принципе возможно благодаря полиморфизму, без знания шаблона стратегии, это оставило бы вас с проблемой "изобретать колесо" для решения этой конкретной проблемы. В заключение они очень разные, даже если они основаны на другом. Я оставлю вас, чтобы увидеть код "Ender Muab'Dib", так как это хорошо объяснено, если вы все еще хотите, чтобы код из моего кода просто спросил, приветствия и надеюсь, что я помог.