如何重构多个复杂的if-else分支

时间:2011-06-03 11:54:31

标签: refactoring structure if-statement

此问题适用于组织活动的公司使用的软件。当活动发生变化(状态,开始时间,人数)时,需要通知某些人(通过电子邮件)。负责此操作的代码非常简单:电子邮件正文包含所有旧值和已更改信息的新值。

多年来,引入了许多小规则。例如:如果新状态为“已取消”,则邮件主题应为:“活动已取消”而不是“活动已更改”。如果没有先前状态(因此活动是新的),并且当前状态为“最终”,则主题应为“[日期]上的新活动”,并且正文应包含完整概述(因此不进行更改)。

上述规则仅用于说明问题。还有更多的(关于状态/日期/时间/等的组合),总共最多约500行代码。

出现的问题是此代码目前很难理解和维护。不时引入新规则,在不破坏其他规则的情况下添加它们可能会很痛苦。将这样的代码重写为更易理解和可维护的代码的最佳方法是什么?目前,if-else分支的顺序也非常重要。第一个if语句是最重要的,下一个else-if语句稍微不那么重要,直到最常见情况的最后一个else子句。

2 个答案:

答案 0 :(得分:4)

听起来像rules engine可以帮助的东西。 Drools是一种选择,但它几乎肯定是完全矫枉过正的!

您是否有代表规则的界面?像

这样的东西
public class Activity {}

public interface Rule {
     boolean applies(Activity);

     Activity applyRule(Activity x);
}

鉴于此,你可以实现一个reduce函数来按顺序应用规则,直到你到达列表的末尾。

Activity applyRules(List<Rule> rules, Activity);

答案 1 :(得分:2)

我会将规则和应用程序分开,因此您的代码将成为

For all Rules
   if ThisRule.Applies(activity) then
       ThisRule.ApplyActions(email);
       break;

规则将是一个类,其中每个规则都有Applies和ApplyActions或ConstructEmail等。

您按优先顺序构建规则列表。一旦完成,您只需要遍历列表。

这一点的重点是规则不需要了解或关心其他规则,所有规则都是有效独立的,他们只需要知道它们是否是给予它们的活动的规则,如果它们是然后按照该规则的操作进行操作。

困难在于分裂出不同的规则, 例如,如果你有一个规则,其中新的状态被取消,所以你必须在标题中取消,但你有另一个规则也适用,那么你需要一个机制来应用多个规则,如:

For all Rules
   if ThisRule.Applies(activity) then
       ThisRule.ApplyActions(email);
       if ThisRule.TerminalRule then
           break;

因此,更改主题等简单规则也允许应用其他规则。