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

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

Мне трудно понять эти два шаблона проектирования.

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

Спасибо.

enter image description here

enter image description here

4b9b3361

Ответ 1

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

MpegCompression
AviCompression
QuickTimeCompression

и т.д.

Я думаю о шаблоне посетителя как отношение many: many. Скажем, мое приложение растет, чтобы включить не только видео, но и аудиоклипы. Если я придерживаюсь шаблона стратегии, мне придется дублировать классы сжатия - один для видео и один для аудио:

MpegVideoCompression
MpegAudioCompression

и т.д.

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

MpegCompression::compressVideo(Video object)    
MpegCompression::compressAudio(Audio object)

Ответ 2

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

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

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

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

Две стороны одной и той же монеты...

Это имеет смысл?

Ответ 3

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

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

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

Итак, это будет посетитель:

class LightToucher : IToucher{
    string Touch(Head head){return "touched my head";}
    string Touch(Stomach stomach){return "hehehe!";}
}

с другим одним из этого типа

class HeavyToucher : IToucher{
   string Touch(Head head){return "I'm knocked out!";}
   string Touch(Stomach stomach){return "oooof you bastard!";}
}

У нас есть класс, который может затем использовать этого посетителя для выполнения его работы и изменить его на основе:

class Person{
    IToucher visitor;
    Head head;
    Stomach stomach;
    public Person(IToucher toucher)
    {
          visitor = toucher;

          //assume we have head and stomach
    }

    public string Touch(bool aboveWaist)
    {
         if(aboveWaist)
         {
             visitor.Touch(head);
         }
         else
         {
             visitor.Touch(stomach);
         }
    }
}

Итак, если мы это сделаем           var person1 = new Person (новый LightToucher());           var person2 = new Person (новый HeavyToucher());

        person1.Touch(true); //touched my head
        person2.Touch(true);  //knocked me out!

Ответ 4

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

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

Надеюсь, это поможет вам запомнить:)

Ответ 5

Я вижу стратегический шаблон как способ впрыска метода/стратегии в объект, но обычно подпись этого метода принимает некоторые значения params и возвращает результат, чтобы он не сочетался с пользователем стратегии: Из Википедия:

class Minus : ICalculateStrategy {
    public int Calculate(int value1, int value2) {
        return value1 - value2;
    }
}

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

public class BlisterPack
{
    // Pairs so x2
    public int TabletPairs { get; set; }
}

public class Bottle
{
    // Unsigned
    public uint Items { get; set; }
}

public class Jar
{
    // Signed
    public int Pieces { get; set; }
}

public class PillCountVisitor : IVisitor
{
    public int Count { get; private set; }

    #region IVisitor Members

    public void Visit(BlisterPack blisterPack)
    {
        Count += blisterPack.TabletPairs * 2;
    }

    public void Visit(Bottle bottle)
    {
        Count += (int) bottle.Items;
    }

    public void Visit(Jar jar)
    {
        Count += jar.Pieces;
    }

    #endregion
}

public class BlisterPack : IAcceptor
{
    public int TabletPairs { get; set; }

    #region IAcceptor Members

    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }

    #endregion
}

Как вы видите, у посетителя есть состояние (public int Count), и он работает с списком известных типов BlisterPack, Bottle, Jar. Поэтому, если вы хотите поддерживать новый тип, вам нужно изменить всех посетителей, добавив этот тип.

Также он связан с типами, в которых он работает, из-за "visitor.Visit(this);". Что произойдет, если я удалю или изменю флажок формы "Элементы"?... все посетители потерпят неудачу.

Ответ 6

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

Ответ 7

Если у вас есть только один контекст или элемент и вам нужно выполнить разные операции в этом контексте, вы можете выбрать Strategy Pattern. Это 1:M relationship, упомянутый в приведенном выше ответе. java.util.Comparator является хорошим примером шаблона проектирования стратегии в действии. Там мы можем иметь разные стратегии сортировки для одной коллекции (контекст или элемент).

С другой стороны, скажем, что у вас есть несколько исполнителей, все соответствуют общему контракту и вам нужно выполнить разные операции над каждым из них. В качестве примера рассмотрим утилизацию автомойки, в которой у вас есть тело, двигатель и колесо и т.д., И каждый из них можно мыть, используя пар или воду. Это хорошее использование Visitor Pattern. Но убедитесь, что ваши контекстные элементы остаются неизменными и никогда не меняются. Если элементы будут меняться, добавив в Car элемент Door, то вам нужно будет изменить всех посетителей, добавив в каждый из них один новый метод и нарушив характер шаблона OCP. Таким образом, это отношение M:N, указанное в приведенном выше ответе.

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

Ответ 8

Их отличия заключаются в следующем:

  • Мотивация
  • Намерение
  • Реализация

Не уверен, что получается из сравнения двух разных вещей, но сравните Strategy с Visitor.

Что же касается этих двух, чтобы взглянуть на их различия?