需要重构箭头反模式的想法 [英] Need refactoring ideas for Arrow Anti-Pattern

查看:19
本文介绍了需要重构箭头反模式的想法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承了一个怪物.

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

It is masquerading as a .NET 1.1 application processes text files that conform to Healthcare Claim Payment (ANSI 835) standards, but it's a monster. The information being processed relates to healthcare claims, EOBs, and reimbursements. These files consist of records that have an identifier in the first few positions and data fields formatted according to the specs for that type of record. Some record ids are Control Segment ids, which delimit groups of records relating to a particular type of transaction.

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

To process a file, my little monster reads the first record, determines the kind of transaction that is about to take place, then begins to process other records based on what kind of transaction it is currently processing. To do this, it uses a nested if. Since there are a number of record types, there are a number decisions that need to be made. Each decision involves some processing and 2-3 other decisions that need to be made based on previous decisions. That means the nested if has a lot of nests. That's where my problem lies.

这个嵌套的 if 有 715 行长.是的,这是正确的.七百零五条线.我不是代码分析专家,所以我下载了几个免费软件分析工具,得出的 McCabe Cyclomatic Complexity 评级为 49.他们告诉我这是一个相当高的数字.亚特兰大地区的花粉计数很高,100 是高的标准,新闻说今天的花粉计数为 1,523".这是我有幸看到的箭头反模式的最佳示例之一.最高时,缩进深度为 15 个标签.

This one nested if is 715 lines long. Yes, that's right. Seven-Hundred-And-Fif-Teen Lines. I'm no code analysis expert, so I downloaded a couple of freeware analysis tools and came up with a McCabe Cyclomatic Complexity rating of 49. They tell me that's a pretty high number. High as in pollen count in the Atlanta area where 100 is the standard for high and the news says "Today's pollen count is 1,523". This is one of the finest examples of the Arrow Anti-Pattern I have ever been priveleged to see. At its highest, the indentation goes 15 tabs deep.

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

My question is, what methods would you suggest to refactor or restructure such a thing?

我花了一些时间寻找想法,但没有什么能让我站稳脚跟.例如,将级别替换为保护条件是一种方法.我只有其中之一.一窝下来,十四去.

I have spent some time searching for ideas, but nothing has given me a good foothold. For example, substituting a guard condition for a level is one method. I have only one of those. One nest down, fourteen to go.

也许有一种设计模式可能会有所帮助.指挥链能解决这个问题吗?请记住,它必须保留在 .NET 1.1 中.

Perhaps there is a design pattern that could be helpful. Would Chain of Command be a way to approach this? Keep in mind that it must stay in .NET 1.1.

感谢您的任何想法.

推荐答案

这周我刚刚处理了一些与您所描述的类似(虽然没有那么可怕)的遗留代码.

I just had some legacy code at work this week that was similar (although not as dire) as what you are describing.

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

There is no one thing that will get you out of this. The state machine might be the final form your code takes, but thats not going to help you get there, nor should you decide on such a solution before untangling the mess you already have.

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

First step I would take is to write a test for the existing code. This test isn't to show that the code is correct but to make sure you have not broken something when you start refactoring. Get a big wad of data to process, feed it to the monster, and get the output. That's your litmus test. if you can do this with a code coverage tool you will see what you test does not cover. If you can, construct some artificial records that will also exercise this code, and repeat. Once you feel you have done what you can with this task, the output data becomes your expected result for your test.

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

Refactoring should not change the behavior of the code. Remember that. This is why you have known input and known output data sets to validate you are not going to break things. This is your safety net.

现在重构!

我做了一些我觉得有用的事情:

A couple things I did that i found useful:

反转 if 语句

Invert if statements

我在阅读代码时遇到的一个大问题是找不到相应的else语句,我注意到很多块看起来像这样

A huge problem I had was just reading the code when I couldn't find the corresponding else statement, I noticed that a lot of the blocks looked like this

if (someCondition)
{
  100+ lines of code
  {
    ...
  }
}
else
{
  simple statement here
}

通过反转 if 我可以看到简单的情况,然后移动到更复杂的块,知道另一个已经做了什么.变化不大,但帮助我理解.

By inverting the if I could see the simple case and then move onto the more complex block knowing what the other one already did. not a huge change, but helped me in understanding.

提取方法

我经常用这个.拿一些复杂的多行块,用它自己的方法把它推到一边.这让我可以更轻松地看到代码重复的地方.

I used this a lot.Take some complex multi line block, grok it and shove it aside in it's own method. this allowed me to more easily see where there was code duplication.

现在,希望您没有破坏您的代码(测试仍然通过对吗?),并且您有更易读和更好理解的过程代码.看它已经改进了!但是你之前写的那个测试真的不够好......它只告诉你你复制了原始代码的功能(错误和所有),而且那只是你覆盖的那一行,因为我相信你会找到你不知道如何命中或永远无法命中的代码块(我在我的作品中都见过).

Now, hopefully, you haven't broken your code (test still passes right?), and you have more readable and better understood procedural code. Look it's already improved! But that test you wrote earlier isn't really good enough... it only tells you that you a duplicating the functionality (bugs and all) of the original code, and thats only the line you had coverage on as I'm sure you would find blocks of code that you can't figure out how to hit or just cannot ever hit (I've seen both in my work).

现在所有大牌模式发挥作用的重大变化是,当您开始考虑如何以适当的面向对象方式重构时.给这只猫剥皮的方法不止一种,而且会涉及多种模式.由于不知道您正在解析的这些文件的格式的详细信息,我只能提出一些有用的建议,这些建议可能是也可能不是最佳解决方案.

Now the big changes where all the big name patterns come into play is when you start looking at how you can refactor this in a proper OO fashion. There is more than one way to skin this cat, and it will involve multiple patterns. Not knowing details about the format of these files you're parsing I can only toss around some helpful suggestions that may or may not be the best solutions.

重构为模式协助解释在这些情况下有用的模式.

Refactoring to Patterns is a great book to assist in explainging patterns that are helpful in these situations.

你想吃一头大象,除了一次咬一口,别无他法.祝你好运.

You're trying to eat an elephant, and there's no other way to do it but one bite at a time. Good luck.

这篇关于需要重构箭头反模式的想法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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