Как заменить (а не просто переместить) условную логику на стратегию? - PullRequest
2 голосов
/ 11 сентября 2010

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

Книга DP забивает одну и ту же иллюзию:

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

void Composition::Repair () {
    switch (_breakingStrategy) {
    case SimpleStrategy:
        ComposeWithSimpleCompositor();
        break;
    case TeXStrategy:
        ComposeWithTeXCompositor();
        break;
    // ...
    }
    // merge results with existing composition, if necessary
}

Шаблон Стратегия устраняет эту инструкцию, делегируя перевод строки в объект Стратегии:

void Composition::Repair () {
    _compositor->Compose();
    // merge results with existing composition, if necessary
}

Да, но как выбрать класс Стратегии для создания экземпляра композитора? Условная логика? Я вижу, что если бы у контекста была задержка, то условная логика была бы еще дальше, так как каждый подкласс мог бы создать экземпляр соответствующей Стратегии, но это также применимо к Composition :: repair (), где каждый подкласс вместо этого напрямую вызывал бы ComposeWithSimpleCompositor из ComposeWithTeXCompositor.

Ответы [ 2 ]

4 голосов
/ 11 сентября 2010

Да - выбор шаблона проектирования иногда перемещает логику, а не заменяет ее.

Хотя я не совсем понимаю ваше возражение. Некоторая часть логики принятия решения уже в клиенте, и стратегия консолидирует решение.

В вашем примере кода

void Composition::Repair () {
    switch (_breakingStrategy) {
    case SimpleStrategy:
        ComposeWithSimpleCompositor();
        break;
    case TeXStrategy:
        ComposeWithTeXCompositor();
        break;
    // ...
    }
    // merge results with existing composition, if necessary
}

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

Единственное, что применяет Стратегия, - это принятие решения, предоставляющего подкласс Стратегии, а не «код типа», как сейчас, консолидирующего решение.

Решение, конечно, должно быть где-то принято. Если вы чувствуете, что метод Composition::Repair является подходящим местом для него, вы, конечно, можете вообще не использовать шаблон Стратегии.

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

0 голосов
/ 23 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...