В чем разница между шаблонным методом и паттернами стратегии?

StackOverflow https://stackoverflow.com/questions/669271

Вопрос

Может кто-нибудь объяснить мне, в чем разница между шаблоном метода шаблона и шаблоном стратегии?

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

Однако, насколько клиент обеспокоен тем, что они потребляются точно так же - это правильно?

Это было полезно?

Решение

Основное различие между ними заключается в выборе конкретного алгоритма.

С Шаблон метода шаблона это происходит в время компиляции к создание подклассов шаблон.Каждый подкласс предоставляет свой конкретный алгоритм, реализуя абстрактные методы шаблона.Когда клиент вызывает методы внешнего интерфейса шаблона, шаблон вызывает свои абстрактные методы (свой внутренний интерфейс), необходимые для вызова алгоритма.

class ConcreteAlgorithm : AbstractTemplate
{
    void DoAlgorithm(int datum) {...}
}

class AbstractTemplate
{
    void run(int datum) { DoAlgorithm(datum); }

    virtual void DoAlgorithm() = 0; // abstract
}

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

class ConcreteAlgorithm : IAlgorithm
{
    void DoAlgorithm(int datum) {...}
}

class Strategy
{
    Strategy(IAlgorithm algo) {...}

    void run(int datum) { this->algo.DoAlgorithm(datum); }
}

В итоге:

  • Шаблон метода шаблона: время компиляции выбор алгоритма по создание подклассов
  • Шаблон стратегии: алгоритм времени выполнения выбор по сдерживание

Другие советы

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

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

Эти два шаблона можно легко использовать вместе.У вас может быть шаблон стратегии, в котором несколько реализаций принадлежат семейству стратегий, реализованных с использованием шаблона шаблона.

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

Стратегия
Инкапсулирует алгоритм внутри класса
Ссылка на изображение enter image description here

Шаблонный метод
Перенесите точные шаги алгоритма в подкласс
Ссылка на изображение enter image description here

Вы, вероятно, имеете в виду шаблон метода шаблона.Вы правы, они служат очень схожим потребностям.Я бы сказал, что лучше использовать метод шаблона в тех случаях, когда у вас есть «шаблонный» алгоритм с определенными шагами, где подклассы переопределяют эти шаги, чтобы изменить некоторые детали.В случае со стратегией вам нужно создать интерфейс, а вместо наследования вы используете делегирование.Я бы сказал, что это немного более мощный шаблон и, возможно, лучше в соответствии с принципами инверсии зависимостей DIP.Он более мощный, потому что вы четко определяете новую абстракцию стратегии — способ сделать что-то, который не применим к шаблонному методу.Итак, если эта абстракция имеет смысл — используйте ее.Однако использование шаблонного метода может дать вам более простые конструкции в простых случаях, что также важно.Подумайте, какие слова подходят лучше:у вас есть шаблонный алгоритм?Или главное здесь то, что у вас есть абстракция стратегии — новый способ сделать что-то.

Пример шаблонного метода:

Application.main()
{
Init();
Run();
Done();
}

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

Пример стратегии:

array.sort (IComparer<T> comparer)

Здесь при написании компаратора вы не наследуетесь от массива.Array делегирует алгоритм сравнения компаратору.

Difference between Strategy and Template Method Pattern Strategy vs Template method


Сходства

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


Различия

Вот некоторые различия, которые я заметил при изучении этих двух паттернов:

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

Изображение взято с сайта маленький блог.

Наследование против агрегации (is-a против has-a).Это два способа достижения одной и той же цели.

Этот вопрос показывает некоторые компромиссы между вариантами: Наследование против.Агрегация

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

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

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

Шаблонный метод:

  1. Это основано на наследование
  2. Определяет скелет алгоритма, который не может быть изменен подклассами.В подклассах могут быть переопределены только определенные операции.
  3. Родительский класс полностью управляет алгоритмом и отличается лишь определенными шагами к конкретным классам
  4. Связывание выполняется во время компиляции

Шаблон_метод состав:

enter image description here

Стратегия:

  1. Это основано на делегация/состав
  2. Это меняет внутренности объекта путем изменения поведения метода
  3. Раньше это было переключение между семейством алгоритмов
  4. Он полностью меняет поведение объекта во время выполнения. замена одного алгоритма другим алгоритмом во время выполнения
  5. Привязка выполняется во время выполнения

Стратегия состав:

enter image description here

Посмотри на Шаблонный метод и Стратегия статьи для лучшего понимания.

Похожие сообщения:

Шаблон проектирования шаблонов в JDK: не удалось найти метод, определяющий набор методов, которые должны выполняться по порядку.

Реальный пример паттерна стратегии

Нет, они не обязательно потребляются одинаково.Шаблон «метод шаблона» — это способ предоставить «руководство» будущим разработчикам.Вы говорите им: «Все объекты Person должны иметь номер социального страхования» (это тривиальный пример, но он правильно передает идею).

Модель стратегии позволяет несколько возможные реализации, которые можно включать и выключать.Это (обычно) реализуется не через наследование, а вместо этого позволяет вызывающему объекту передать желаемую реализацию.Примером может быть предоставление ShippingCalculator одного из нескольких различных способов расчета налогов (возможно, реализация NoSalesTax и реализация PercentageBasedSalesTax).

Поэтому иногда клиент фактически сообщит объекту, какую стратегию использовать.Как в

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

Но клиент никогда не сделал бы этого с объектом, основанным на шаблонном методе.Фактически, клиент может даже не знать, что объект основан на методе шаблона.Эти абстрактные методы в шаблоне «Метод шаблона» могут даже быть защищены, и в этом случае клиент даже не узнает об их существовании.

Я бы посоветовал вам прочитать этот статья.Объясняются различия на реальном примере.

Цитата из статьи

"Как можно увидеть реализацию классов, также зависят от класса метода шаблона.Эта зависимость заставляет изменять метод шаблона, если кто -то хочет изменить некоторые шаги алгоритма.На другой стороне стратегии полностью инкапсулирует алгоритм.Это дает классам реализации полностью определить алгоритм.Поэтому, если какое -либо изменение поступает, необходимо изменить код для ранее написанных классов.Это была основная причина, по которой я выбираю стратегию для разработки классов.

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

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

Стратегия также позволяет изменять алгоритм во время выполнения.В методе шаблона нужно будет повторно инициализировать объект.Эта особенность стратегии обеспечивает большую гибкость.С точки зрения дизайна нужно предпочесть композицию в отношении наследования.Поэтому использование стратегического шаблона также стало основным выбором для разработки ».

Паттерн «Шаблон» аналогичен паттерну «Стратегия».Эти две модели различаются по объему и методологии.

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

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

от http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html

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

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

Шаблон проектирования стратегии

  • Поддерживает композицию.
  • Предоставляет вам возможность изменять поведение объекта во время выполнения.
  • Меньшая связь между клиентским кодом и кодом решения/алгоритма.

Шаблон проектирования шаблонного метода

  • Предпочитает наследование по композиции
  • Определите алгоритм в своем базовом классе.Отдельные части алгоритма можно настроить в дочерних классах.

Шаблон шаблона:

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

public abstract class RobotTemplate {
    /* This method can be overridden by a subclass if required */
    public void start() {
        System.out.println("Starting....");
    }

    /* This method can be overridden by a subclass if required */
    public void getParts() {
        System.out.println("Getting parts....");
    }

    /* This method can be overridden by a subclass if required */
    public void assemble() {
        System.out.println("Assembling....");
    }

    /* This method can be overridden by a subclass if required */
    public void test() {
        System.out.println("Testing....");
    }

    /* This method can be overridden by a subclass if required */
    public void stop() {
        System.out.println("Stopping....");
    }

    /*
     * Template algorithm method made up of multiple steps, whose structure and
     * order of steps will not be changed by subclasses.
     */
    public final void go() {
        start();
        getParts();
        assemble();
        test();
        stop();
    }
}


/* Concrete subclass overrides template step methods as required for its use */
public class CookieRobot extends RobotTemplate {
    private String name;

    public CookieRobot(String n) {
        name = n;
    }

    @Override
    public void getParts() {
        System.out.println("Getting a flour and sugar....");
    }

    @Override
    public void assemble() {
        System.out.println("Baking a cookie....");
    }

    @Override
    public void test() {
        System.out.println("Crunching a cookie....");
    }

    public String getName() {
        return name;
    }
}

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

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

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

/**
 * This Strategy interface is implemented by all concrete objects representing an
 * algorithm(strategy), which lets us define a family of algorithms.
 */
public interface Logging {
    void write(String message);
}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class ConsoleLogging implements Logging {

    @Override
    public void write(String message) {
        System.out.println(message); 
    }

}

/**
 * Concrete strategy class representing a particular algorithm.
 */
public class FileLogging implements Logging {

    private final File toWrite;

    public FileLogging(final File toWrite) {
        this.toWrite = toWrite;
    }

    @Override
    public void write(String message) {
        try {
            final FileWriter fos = new FileWriter(toWrite);
            fos.write(message);
            fos.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

}

Полный исходный код можно найти на моем github. репозиторий.

Стратегия представлена ​​как интерфейс, а метод шаблона — как абстрактный класс.Обычно это часто используется в фреймворках.напримерКласс MessageSource среды Spring — это стратегический интерфейс для разрешения сообщений.Клиент использует конкретную реализацию (стратегию) этого интерфейса.

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

http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html

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

Имя шаблона. Метод шаблона означает, что это такое.Допустим, у нас есть метод CalculateSomething(), и мы хотим создать шаблон этого метода.Этот метод будет объявлен в базовом классе как невиртуальный метод.Скажем, метод выглядит так.

CalculateSomething(){
    int i = 0;
    i = Step1(i);
    i++;
    if (i> 10) i = 5;
    i = Step2(i);
    return i;

} Реализация метода шага1 и шага 2 может быть задана полученными классами.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top