If statement 需要重构Arrow反模式的想法吗

If statement 需要重构Arrow反模式的想法吗,if-statement,nested,refactoring,anti-patterns,If Statement,Nested,Refactoring,Anti Patterns,我继承了一个怪物 它伪装成一个.NET1.1应用程序处理符合医疗索赔支付(ANSI 835)标准的文本文件,但它是一个怪物。正在处理的信息涉及医疗索赔、EOB和报销。这些文件包括在前几个位置具有标识符的记录和根据该类型记录的规范格式化的数据字段。一些记录ID是控制段ID,用于界定与特定事务类型相关的记录组 为了处理文件,我的小怪物读取第一条记录,确定即将发生的事务类型,然后根据当前正在处理的事务类型开始处理其他记录。为此,它使用嵌套的if。由于有许多记录类型,因此需要做出许多决定。每个决策都涉及

我继承了一个怪物

它伪装成一个.NET1.1应用程序处理符合医疗索赔支付(ANSI 835)标准的文本文件,但它是一个怪物。正在处理的信息涉及医疗索赔、EOB和报销。这些文件包括在前几个位置具有标识符的记录和根据该类型记录的规范格式化的数据字段。一些记录ID是控制段ID,用于界定与特定事务类型相关的记录组

为了处理文件,我的小怪物读取第一条记录,确定即将发生的事务类型,然后根据当前正在处理的事务类型开始处理其他记录。为此,它使用嵌套的if。由于有许多记录类型,因此需要做出许多决定。每个决策都涉及一些处理和2-3个其他决策,需要根据以前的决策做出。这意味着嵌套if有很多嵌套。这就是我的问题所在

这个嵌套的if是715行。是的,没错。750条青少年线路。我不是代码分析专家,所以我下载了两个免费软件分析工具,得出了McCabe圈复杂度等级49。他们告诉我这是一个相当高的数字。高达亚特兰大地区的花粉数量,100是高的标准,新闻说“今天的花粉数量是1523”。这是我有幸看到的箭头反模式的最好例子之一。在其最高处,压痕深度为15个标签

我的问题是,你会建议用什么方法来重构这样的东西

我花了一些时间寻找想法,但没有什么能给我一个好的立足点。例如,将保护条件替换为级别是一种方法。我只有一个。下一窝,还剩十四窝

也许有一种设计模式会有所帮助。指挥链是解决这个问题的一种方法吗?请记住,它必须留在.NET1.1中

感谢您提出的所有想法。

A似乎是一个合乎逻辑的起点,如果您可以使用WF(听起来您不行)

您仍然可以在没有WF的情况下实现一个,您只需自己完成即可。然而,从一开始就把它看作一个状态机可能会给你一个更好的实现,而不是创建一个检查每个动作内部状态的过程怪物

绘制出你的状态图,是什么导致了转变。处理记录的实际代码应该被分解出来,并在状态执行时调用(如果特定状态需要)

所以State1的execute调用您的“reada record”,然后根据该记录转换到另一个状态


下一个状态可能读取多个记录并调用记录处理指令,然后转换回状态1。

根据描述判断,状态机可能是处理它的最佳方式。使用enum变量存储当前状态,并将处理作为记录上的循环来实现,使用switch或if语句根据当前状态和输入数据选择要采取的操作。如果工作量过大,也可以使用函数指针根据状态轻松地将工作分派到单独的函数。

。我只遇到过一次这种反模式,我基本上就是按照他的步骤来做的。

在这种情况下,我要做的一件事就是使用“组合方法”模式。关于这个问题,请参见。基本思想是使用IDE中的重构工具来提取有意义的小方法。一旦完成了这项工作,就可以进一步重构和提取有意义的类

有时我会将状态模式与堆栈相结合

它适用于层次结构;父元素知道将什么状态推送到堆栈上以处理子元素,但子元素不必知道关于其父元素的任何信息。换句话说,子对象不知道下一个状态是什么,它只是发出“完成”的信号,然后从堆栈中弹出。这有助于通过保持依赖项单向性来将状态彼此解耦


它非常适合使用SAX解析器处理XML(内容处理程序只需在元素进入和退出时推送和弹出状态以更改其行为)。EDI也应该采用这种方法。

我本周刚在工作中得到了一些与您描述的类似(尽管没有那么可怕)的遗留代码

没有一件事能让你摆脱困境。这可能是您的代码所采用的最终形式,但这不会帮助您实现这一目标,您也不应该在解决现有的混乱之前决定这样的解决方案

我将采取的第一步是为现有代码编写测试。这个测试不是为了证明代码是正确的,而是为了确保在开始重构时没有破坏某些东西。获取大量要处理的数据,将其提供给怪物,然后获得输出。这是你的试金石。如果您可以使用代码覆盖率工具来实现这一点,您将看到测试没有覆盖的内容。如果可以的话,构造一些人工记录,这些记录也将执行此代码,然后重复。一旦您觉得已经完成了此任务,输出数据将成为您测试的预期结果

重构不应该改变代码的行为。记住这一点。这就是为什么您有已知的输入和输出数据集来验证您不会破坏东西。这是你的安全网

现在重构

我做了一些有用的事情:

反转
if
语句

我遇到的一个大问题是,当我在读代码时,找不到相应的
else
语句,我注意到很多块
if (someCondition)
{
  100+ lines of code
  {
    ...
  }
}
else
{
  simple statement here
}