Когда и почему Стратегическая модель должна использоваться?

Как насчет этого?

cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'

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

tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps
26
задан Thomas Owens 10 November 2009 в 20:31
поделиться

10 ответов

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

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

58
ответ дан 28 November 2019 в 06:22
поделиться

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

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

  int mod = new ConcreteStrategy(){ 
         public int execute(int a, int b){ return a %b; }
  }.execute(3,4);
4
ответ дан 28 November 2019 в 06:22
поделиться

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

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

2
ответ дан 28 November 2019 в 06:22
поделиться

Шаблон стратегии полезен в ситуациях, когда вы (или пользователи вашего кода) можете захотеть изменить вычисления в ваших алгоритмах. Простой пример, в котором я использовал шаблон стратегии, - это моделирование эвристики в поиске A *. A * использует эвристику, которая представляет собой простые вычисления для оценки оставшейся стоимости, если на пути к целевому узлу (Ng) выбран определенный узел (Ni). Мой интерфейс выглядел примерно так:

class Heuristic {
public:
    virtual int estimateRemainingCost(const node &Ni, const node &Ng) const = 0;
};

И они используются следующим образом:

...
// for each node (Ni) that is adjacent to the current node Nc
int node_priority = cost(Ni)/* the cost of choosing this node on the path */
                    + heuristic->estimateRemainingCost(Ni, Ng);
unsearched_nodes_.queue(node_priority, Ni);
...

Эвристика - это стратегии или вычисления, которые можно заменить. Другими словами, изменение эвристики алгоритма поиска - тривиальное упражнение.

1
ответ дан 28 November 2019 в 06:22
поделиться

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

У нас есть конкретный объект, скажем, NSTableView . Табличное представление должно знать, сколько в нем строк, что входит в каждую строку, каждый столбец и т. Д. Поэтому вместо создания подклассов табличного представления для предоставления этой информации мы предоставляем объект «делегат». Этот объект делегата реализует определенный интерфейс («протокол» в Objective-C). Затем tableview может просто спросить своего делегированного объекта, что он должен делать в определенных ситуациях («сколько строк у меня есть?» «Что находится в этой ячейке?» «Разрешено ли пользователю выбирать эту строку?»).

2
ответ дан 28 November 2019 в 06:22
поделиться

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

Один из способов сделать это (в Java):

Map<String, Strategy> strategyMap = new HashMap<String, Strategy>();
strategyMap.put("bark", new BarkingStrategy());
strategyMap.put("meow", new MeowingStrategy());
strategyMap.put("moo", new MooingStrategy());
strategyMap.put("giraffeSound", new UnknownStrategy());

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

] Позже ...

String command = //...some form of input
strategyMap.get(command).execute();

Таким образом, вы можете «в общем» обрабатывать множество различных ситуаций.

то есть:

moo

будет выполнять MooingStrategy ()

0
ответ дан 28 November 2019 в 06:22
поделиться

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

0
ответ дан 28 November 2019 в 06:22
поделиться

Это имеет больше смысла, когда объект контекста имеет больше обязанностей, а абстракция стратегии отделяет эти обязанности от некоторого аспекта операции. Одним из примеров (в C #) является интерфейс IComparer:

interface IComparer<T>
{
    int Compare(T a, T b);
}

, который может быть передан в алгоритм сортировки.

0
ответ дан 28 November 2019 в 06:22
поделиться

На ум приходят:

  • Распределитель ресурсов. При ручном управлении ресурсами это может сводить к минимуму время, необходимое для выделения ресурса, или минимизировать фрагментацию. Каждая стратегия здесь имеет метод «Распределить» с одинаковым интерфейсом, при этом пользователь принимает решение о том, какую стратегию использовать, в зависимости от того, что они пытаются оптимизировать.
  • Метод подключения и отправки сетевых данных. Возможно, в некоторых случаях вы предпочтете подключаться и отправлять дейтаграммы UDP, может быть, в других ситуациях, когда производительность была менее важным фактором, который вы бы отправили с использованием TCP / IP.
  • Стратегия форматирования / сериализации данных. Позвольте коду решать, следует ли сериализовать объект с помощью Json или Xml. Может быть, один для машин, а другой для читаемых человеком ситуаций. Обе стратегии имеют " Я знаю, что скрывается под капотом, только то, что интерфейс будет доволен. Пользователям стратегии не нужно знать, почему мы приняли решение. Им просто нужно совершить действие. Мы принимаем решение один раз и передаем стратегию классам, которые используют эту стратегию.

    Например, рассмотрим случай, когда мы принимаем решение в масштабе всей программы, основанное на данной конфигурации сети, для подключения и отправки данных на удаленный компьютер. хосты с UDP. Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

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

    Например, рассмотрим случай, когда мы принимаем решение в масштабе всей программы, основанное на данной конфигурации сети, для подключения и отправки данных на удаленный компьютер. хосты с UDP. Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

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

    Например, рассмотрим случай, когда мы принимаем решение в масштабе всей программы, основанное на данной конфигурации сети, для подключения и отправки данных на удаленный компьютер. хосты с UDP. Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

    Мы принимаем решение один раз и передаем стратегию классам, которые используют эту стратегию.

    Например, рассмотрим случай, когда мы принимаем решение в масштабе всей программы, основанное на данной конфигурации сети, для подключения и отправки данных на удаленный компьютер. хосты с UDP. Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

    Мы принимаем решение один раз и передаем стратегию классам, которые используют эту стратегию.

    Например, рассмотрим случай, когда мы принимаем решение в масштабе всей программы, основанное на данной конфигурации сети, для подключения и отправки данных на удаленный компьютер. хосты с UDP. Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

    Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

    Вместо того, чтобы каждый пользователь сетевого интерфейса должен знать логику для принятия решения (функция «DoIt» выше), мы можем заранее создать стратегию UDP и передать ее всем, кому нужно отправлять сетевые данные. Затем эта стратегия реализует простой интерфейс с тем же конечным результатом - данные передаются от A к B.

8
ответ дан 28 November 2019 в 06:22
поделиться

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

Например, реализация Context.executeStrategy () может быть такой:

public int executeStrategy(int baseValue, int exponentFactor)
{
    return (int) Math.Pow(baseValue, this.Strategy.Calculate(2, exponentFactor));
}
0
ответ дан 28 November 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: