重构内部循环,在级别之间存在大量依赖关系

Tej*_*eer 6 c# java convention for-loop nested

我有以下preudo代码

using (some web service/disposable object)
{
    list1 = service.get1();

    list2 = service.get2();

    for (item2 in list2)
    {
        list3 = service.get3(depending on item2);

        for (item3 in list3)
        {
            list4 = service.get4(depending on item3 and list1);

            for (item4 in list4)
            {
                ...
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在整个代码所在的位置,假设有500行,在for语句中有很多逻辑.问题是将其重构为可读和可维护的代码,并作为类似情况的最佳实践.以下是我到目前为止找到的可能解决方案.

1:拆分成方法 考虑到我们将每个提取for到自己的方法中,为了提高可读性,我们最终得到了method2,method3和method4.每个方法都有自己的参数和依赖关系,除了method4之外,这很好.Method4依赖于list1,这意味着list1也必须传递给方法2和3.从我的观点来看,这变得难以理解.任何看着method2的开发人员都会意识到list1里面没有任何意义,所以他必须向下看,直到method4实际实现依赖 - >效率低下.那么,如果list4或item4发生变化并且不再需要依赖于list1会发生什么?我必须删除method4的list1参数(当然应该这样做),但是对于方法2和3(超出更改范围) - >再次低效.另一个副作用是,在许多依赖关系和多个级别的情况下,传递的参数数量将迅速增加.想想如果list4还依赖于list11,list12和list13,会发生什么,这些都是在list1级别创建的.

2:保持长单一方法 优点是每个列表和项目都可以访问每个父列表和项目,这使得进一步的更改成为一个单行.如果list4不再依赖于list1,只需删除/替换代码,而不更改其他任何内容.显然,问题是该方法是几百行,我们都知道它不好.

3.两全其美? 这个想法是将方法分解为每个方法的内部逻辑部分for.这样,主要方法将减少,我们获得可读性和可能的​​可维护性.离开for主要方法,我们仍然可以作为一个单行访问每个依赖.我们最终得到这样的东西:

for (item2 in list2)
{
    compute();

    list3 = service.get3(depending on item2);

    for (item3 in list3)
    {
        compute(item2, eventually item1)

        list4 = service.get4(depending on item3 and list1);

        for (item4 in list4)
        {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但还有另一个问题.compute为了便于阅读,您如何命名这些方法?假设我有一个局部变量instanceA或类型ClassA,我从item2填充.A类包含一个名为LastItem4的属性,它需要按创建日期或其他顺序保留最后一个item4.如果我使用compute来创建instanceA,那么这个计算只是部分的.因为需要在item4级别上填充LastItem4属性,所以在不同的计算方法中.那么如何调用这两种计算方法来表明我实际在做什么呢?在我看来,答案很难.

4. #region 保留一个长方法但使用区域.这是一些在某些编程语言中严格使用的功能,在我看来像是一个补丁,不是最佳实践,但也许只是我.

我想知道你将如何进行这种重构?请注意,它可能比这更复杂.事实是一个服务有点误导,我的想法是我不喜欢使用一次性对象作为方法参数,因为你不知道意图而不读取实际的方法代码.但我在评论中期待这一点,因为其他人可能会感到不同.

举例来说,假设服务是第三方服务,没有可能改变其工作方式.

Tej*_*eer 1

我最终结合使用了问题中描述的解决方案 3 和 DTO。这不一定是最佳选择,但在可读性、灵活性和可扩展性方面比其他选择更好。