如何用策略替换(而不仅仅是移动)条件逻辑?
Posted
技术标签:
【中文标题】如何用策略替换(而不仅仅是移动)条件逻辑?【英文标题】: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。
【问题讨论】:
【参考方案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】:条件逻辑被推向更远的地方,朝向客户端。这可能是可取的,因为很可能在那个方向上已经做出了选择(是的,通过条件逻辑)。这样条件逻辑就被考虑在内了。 做出选择的条件可能有不同的形式,包括文本。
【讨论】:
以上是关于如何用策略替换(而不仅仅是移动)条件逻辑?的主要内容,如果未能解决你的问题,请参考以下文章