【问题标题】:How to Replace (and not just move) Conditional Logic with Strategy?如何用策略替换(而不仅仅是移动)条件逻辑?
【发布时间】:2010-09-10 21:58:32
【问题描述】:

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
}

策略模式通过将换行任务委托给策略对象来消除这种情况声明:

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

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

【问题讨论】:

    标签: design-patterns refactoring


    【解决方案1】:

    是的 - 设计模式的选择有时会移动逻辑而不是替换它。

    不过,我真的不明白你的反对意见。一些决策逻辑已经在客户端中,并且策略巩固了决策。

    在您的代码示例中

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

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

    应用策略唯一要做的就是让决策提供一个策略子类而不是现在的“类型代码”,从而巩固决策。

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

    如果您想使用策略,但不希望客户端中的逻辑(比现有的更多),包含类似开关的工厂方法可以提供它。

    【讨论】:

      【解决方案2】:

      条件逻辑被推向更远的地方,朝向客户端。这可能是可取的,因为很可能在那个方向上已经做出了选择(是的,通过条件逻辑)。这样条件逻辑就被考虑在内了。 做出选择的条件可能有不同的形式,包括文本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多