我继承了一个怪物.
它伪装成.NET 1.1应用程序处理符合医疗保健索赔支付(ANSI 835)标准的文本文件,但它是一个怪物.正在处理的信息涉及医疗保健索赔,EOB和报销.这些文件包含在前几个位置具有标识符的记录,以及根据该类型记录的规范格式化的数据字段.一些记录ID是控制段ID,它分隔与特定类型的事务相关的记录组.
为了处理文件,我的小怪物读取第一条记录,确定即将发生的交易类型,然后根据当前正在处理的交易类型开始处理其他记录.为此,它使用嵌套的if.由于存在多种记录类型,因此需要做出许多决定.每个决策都涉及一些处理和2-3个其他需要根据以前的决策做出的决定.这意味着嵌套if有很多巢.这就是我的问题所在.
这个嵌套if是715行长.恩,那就对了.七百五十条青少年线.我不是代码分析专家,因此我下载了几个免费软件分析工具,并得出了McCabe Cyclomatic Complexity评级为49.他们告诉我这是一个非常高的数字.在亚特兰大地区的花粉数量很高,其中100是高标准,新闻称"今天的花粉数量是1,523".这是我见过的箭头反模式最好的例子之一.在最高处,压痕深度为15个标签.
我的问题是,你建议采用什么方法来重构或重组这样的东西?
我花了一些时间寻找想法,但没有什么能给我一个良好的立足点.例如,用保护条件代替等级是一种方法.我只有其中一个.一窝下来,十四去.
也许有一种设计模式可能会有所帮助.指挥链会成为接近这个的方法吗?请记住,它必须保留在.NET 1.1中.
感谢您提出的所有想法.
我本周在工作中只有一些遗留代码与你所描述的相似(尽管不是那么可怕).
没有任何东西会让你脱离这一点.该状态机可能是最终形式的代码需要,但那不是会帮助你到达那里,也不应该你解开你已经拥有的烂摊子之前,这样的解决方案作出决定.
我要采取的第一步是为现有代码编写测试.此测试不是为了表明代码是正确的,而是为了确保在开始重构时没有破坏某些东西.获取大量数据进行处理,将其提供给怪物,并获得输出.那是你的试金石.如果您可以使用代码覆盖率工具执行此操作,您将看到您测试的内容未涵盖.如果可以的话,构建一些也会运用此代码的人工记录,然后重复.一旦您认为自己已完成了此任务所能完成的任务,输出数据就会成为测试的预期结果.
重构不应该改变代码的行为.记住这一点.这就是为什么您已知输入和已知输出数据集以验证您不会破坏的原因.这是你的安全网.
现在重构!
我发现了一些有用的东西:
反转if
陈述
我遇到的一个大问题是当我找不到相应的else
语句时只是读代码,我注意到很多块看起来像这样
if (someCondition) { 100+ lines of code { ... } } else { simple statement here }
通过反转,if
我可以看到简单的情况,然后移动到更复杂的块,知道另一个已经做了什么.不是一个巨大的变化,但帮助我理解.
提取方法
我经常使用它.使用一些复杂的多行块,然后用它自己的方法将它移开.这让我更容易看到代码重复的位置.
现在,希望你没有破坏你的代码(测试仍然正确?),并且你有更多可读和更好理解的程序代码.看它已经改进了!但是你之前写的那个测试并不是很好......它只告诉你复制了原始代码的功能(bug和all),那只是你所覆盖的那一行,因为我确定你会找到你无法弄清楚如何击中或者无法击中的代码块(我在工作中看到过).
现在所有大牌模式发挥作用的重大变化是,当你开始研究如何以适当的OO方式重构这一点时.皮肤这种猫的方法不止一种,它涉及多种模式.不知道有关您正在解析的这些文件的格式的详细信息,我只能提出一些有用的建议,这些建议可能是也可能不是最佳解决方案.
重构模式是一本很好的书,可以帮助解释在这些情况下有用的模式.
你正试图吃一头大象,除了一口咬一口之外别无他法.祝好运.