design-patterns - 如何用策略替换(而不仅仅是移动)条件逻辑?

标签 design-patterns refactoring

Refactoring to Patterns作者通过让客户使用 Loan 工厂方法来替换条件逻辑,其中每个工厂方法都对给定的参数使用适当的策略。但是,我觉得它已经将条件逻辑代码传递给了客户端,客户端必须根据参数选择调用哪个 Loan 工厂方法。这不是移动而不是替换吗?

DP 书强调了同样的错觉:

例如,如果没有策略,将文本分成多行的代码可能如下所示

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

Strategy 模式通过将换行任务委托(delegate)给 Strategy 对象来消除这种 case 语句:

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

是的,但是如何选择从哪个 Strategy 类中实例化合成器呢?条件逻辑? 我看到如果上下文有层次结构,那么条件逻辑会更远,因为每个子类都可以实例化适当的策略,但这也适用于 Composition::repair() ,每个子类将直接调用 ComposeWithSimpleCompositor的 ComposeWithTeXCompositor.

最佳答案

是的——设计模式的选择有时会移动逻辑而不是取代它。

虽然我不太理解你的反对意见。一些决策逻辑已经在客户端中,策略巩固了决策。

在您的代码示例中

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

_breakingStrategy 字段必须在某处提供,大概由客户端代码决定使用哪种组合方法并将该决定的结果作为 _breakingStrategy 的值传递>.

应用 Strategy 所做的唯一一件事就是让决策提供一个 Strategy 子类而不是像现在这样的“类型代码”,从而巩固决策。

当然必须在某个地方做出决定。如果您觉得 Composition::Repair 方法适合它,您当然可以完全不使用 Strategy 模式。

如果您想使用 Strategy 但不想在客户端中使用逻辑(比现在更多),可以使用包含类似开关的工厂方法。

关于design-patterns - 如何用策略替换(而不仅仅是移动)条件逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3688656/

相关文章:

java - 可选与异常(exception), Controller 与服务

javascript - JS 添加回调来运行下一个函数?

javascript - jQuery:遍历选择器 ID

php - 根据条件参数返回不同的对象

c# - 在 C# 中测试类型安全枚举模式

javascript - 扩展 Zepto.js,不再需要 jQuery

c# - 如何重构顺序ifs?

java - 如何将eclipse中的静态方法移动到不同的类

c - 如何选择函数原型(prototype)的类型?

c# - 相似函数重构模式