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

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

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

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

16 ответов


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

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

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

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

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

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

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

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

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

In резюме:

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

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

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

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


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

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

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

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

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

array.sort (IComparer<T> comparer)

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


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

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

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


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

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


Difference between Strategy and Template Method Pattern Strategy vs Template method


сходство

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


различия

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

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

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


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

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

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


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

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

Template_method структура:

enter image description here

стратегия:

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

стратегия структура:

enter image description here

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

по теме:

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

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


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

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

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

myShippingCalculator.CalculateTaxes(myCaliforniaSalesTaxImpl);

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


Я бы посоветовал вам прочитать этой статьи. Это объясняет различия на примере реального случая.

цитата из статьи

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

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

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

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


шаблон шаблона похож на шаблон стратегии. Эти две модели различаются по масштабу и методологии.

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

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

от 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 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 может быть задана производными классами.

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

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

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