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


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

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

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

16 132

16 ответов:

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

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

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

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

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

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

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

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

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

In резюме:

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

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

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

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

пример a метод шаблона:

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

здесь вы наследуете от приложения и подставляете то, что именно будет сделано на init, run и done.

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

array.sort (IComparer<T> comparer)

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

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

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

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

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

этот вопрос показывает некоторые компромиссы между параметрами: наследование и агрегирование

Difference between Strategy and Template Method Pattern Strategy vs Template method


сходство

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


различия

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

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

изображение берется из bitesized блог.

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

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

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

Метод Шаблона:

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

Template_method структура:

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, на который будет ссылаться субъект, но с шаблоном вы подклассируете базовые и переопределяете методы для внесения изменений.

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

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

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

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

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

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;
    }
}

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

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

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

/**
 * 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 framework - это стратегический интерфейс для разрешения сообщений. Клиент использует конкретную реализацию (стратегию) этого интерфейса.

и абстрактная реализация того же интерфейса AbstractMessageSource, который имеет общую реализацию разрешения сообщений и предоставляет resolvecode () абстрактный метод так, что подклассы могут реализовать их по-своему. 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;

} Реализация метода Step1 и Step2 может быть задана производными классами.

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

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

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