如何用策略替换(而不只是移动)条件逻辑? [英] How to Replace (and not just move) Conditional Logic with Strategy?

查看:84
本文介绍了如何用策略替换(而不只是移动)条件逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重构为模式作者通过让客户使用贷款工厂方法来替换条件逻辑,其中每个方法对给定参数都使用适当的策略。但是,我感觉它已经将条件逻辑代码传递给了客户端,该客户端必须根据贷款工厂方法要调用的参数进行选择。



DP本书对同样的错觉锤击:



,如果没有策略,用于将文本分成几行的代码可能如下:

  void Composition :: Repair(){
开关(_breakingStrategy){
case SimpleStrategy:
ComposeWithSimpleCompositor();
休息时间;
案TeXStrategy:
ComposeWithTeXCompositor();
休息时间;
// ...
}
//将结果与现有组合合并,如有必要
}

策略模式通过将换行任务委托给策略对象来消除此案例陈述:

  void Composition :: Repair(){
_compositor-> Compose();
//将结果与现有组合合并,如有必要
}

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

解决方案

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



不过,我不太理解您的反对意见。某些决策逻辑已经在客户端中,并且策略可以合并决策。



在您的代码示例中

  void Composition :: Repair(){
switch(_breakingStrategy){
case SimpleStrategy:
ComposeWithSimpleCompositor();
休息时间;
案TeXStrategy:
ComposeWithTeXCompositor();
休息时间;
// ...
}
//将结果与现有组合合并,如有必要
}

必须在某个地方提供 _breakingStrategy 字段,大概是由客户端代码确定要使用的编写方法并传递该决策的结果是 _breakingStrategy 的值。



应用策略唯一要做的就是做出决策



当然,必须在某个地方进行决策。



如果您认为 Composition :: Repair 方法是正确的选择,那么您当然可以完全不使用策略模式。



如果您想使用策略,但又不想在客户端中使用逻辑(仅此而已),则可以使用包含类似开关的Factory方法来提供它。


In Refactoring to Patterns the author replaces the conditional logic by having the client use Loan factory methods where each uses the appropriate Strategy for the given arguments. However, I feel like it has passed the conditional logic code to the client, which must choose based on the arguments which Loan factory method to call. Isn't that moving rather than replacing?

The DP book hammers on the same illusion:

For example, without strategies, the code for breaking text into lines could look like

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

The Strategy pattern eliminates this case statement by delegating the linebreaking task to a Strategy object:

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

Yes, but how does one choose from which Strategy class to instantiate compositor? Conditional logic? I see that if the context had a hieararcy, then the conditional logic would be even farther away, since each subclass could instantiate the appropriate Strategy, but that would have also applied to Composition::repair() where each subclass would directly call ComposeWithSimpleCompositor instead of ComposeWithTeXCompositor.

解决方案

Yes - choice of a design pattern sometimes moves logic rather than replacing it.

I don't really understand your objection though. Some of the decision logic is already in the client, and strategy consolidates the decision.

In your code sample

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

the _breakingStrategy field will have to have been supplied somewhere, presumably by the client code determining which composition method to use and passing the result of that decision as the value of _breakingStrategy.

The only thing applying Strategy is doing is making that decision supply a Strategy subclass instead of a "type code" as it is now, consolidating the decision.

The decision does of course have to be made somewhere. If you feel the Composition::Repair method is the right place for it, you are of course free to not use a Strategy pattern at all.

If you want to use Strategy but you don't want the logic in the client (any more than it already is), a Factory Method containing a similar switch could supply it.

这篇关于如何用策略替换(而不只是移动)条件逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆