代码之家  ›  专栏  ›  技术社区  ›  Yawar

在编写代码时,您实际使用了多少嵌套代码块?

  •  4
  • Yawar  · 技术社区  · 15 年前

    我刚刚完成了一个函数的编写,该函数以嵌套代码块结束,如下所示:

    class ... {
      void Method() {
        while (...) {
          ...
          switch (...) {
            while (...) {
              switch (...) {
                if (...) {
                }
              }
            }
          }
        }
      }
    }
    

    在日常的编码工作中,您是否发现这是标准的,或者当您看到类似的情况时,您是否很快开始尝试重新设计和分解代码?

    11 回复  |  直到 11 年前
        1
  •  6
  •   Stefano Borini    15 年前

    不超过三个。作为我的个人哲学。然而,有些情况下你不能做得更好。一个典型的例子是:假设您必须迭代一个6索引矩阵的所有元素。不是你的典型情况,但有时会发生。

    所以,您可以重构出,比如,最里面的三个循环。很好…如何调用重构的例程?

    最后,您会认识到,高度嵌套的循环对于将来的理解是最好的。当然,这是一个特例。如果您确实有高度嵌套的循环和开关(如粘贴的循环和开关),那么您确实有问题,您应该考虑为各个部分提供有意义的名称,将它们隔离,使用对象方向处理开关等。

        2
  •  6
  •   Community T.Woody    7 年前

    我会非常担心 switch -内- 转换 构建。这应该“永远”不会发生。尤其是在像这样的问题面前 this (“使用开关是糟糕的OOP样式?”).

        3
  •  4
  •   Anthony    15 年前

    对于这一点很难设定任何具体的限制,因为有时这只是最好的方法。但是,如果您得到了嵌套得那么深的东西,特别是嵌套循环,有时会给出糟糕的算法,或者在开关内部使用ifs,那么通常可以将事物抽象掉。

    如果我有那么深的东西,我肯定会重构。

        4
  •  3
  •   Mark Simpson    15 年前

    有时会以这种方式结束。我试图关注循环的所有退出条件,等等,看看是否可以简化它们。我还尝试用多态性(如果可行)等来替换开关。

    我还倾向于通过逻辑语句的反转尽可能保持代码的简单(在这里它不会损害可读性)。

    例如。

    而不是这样做:

    public string TransformString(string _input)
    {    
        if(!string.IsNullOrEmpty(_input))
        {
           // do work
           // etc.
    
           return answer;
        }
    
        return null;
    }
    

    这样做:

    public string TransformString(string _input)
    {    
        if(string.IsNullOrEmpty(_input))
             return null;
    
        // do work
        // etc.
    
        return answer;
    }
    

    它有助于保持筑巢和防止躁狂。有时,最好只保留嵌套版本(例如,我不喜欢在复杂的循环体中间键入“continue”关键字,因为它很容易弄乱并引入错误),但我通常更喜欢这种方法:)

        5
  •  2
  •   Daniel A. White    15 年前

    我有时会在代码中发现这一点。但当我到达这一点时,我决定是时候重构了。重构非常关键,因为它允许更干净的代码,并降低了代码的明显复杂性。

        6
  •  2
  •   sal    15 年前

    我在寻找代码嵌套的恐怖故事。我只是花时间用 十六 在最深处筑巢的高度。

    为了增加对伤害的侮辱,整个烂摊子被包裹在:

    try{
      //1527 lines of code, 16 levels deep
    } catch(Exception e) {
      log.error(e.getMessage());
      throw e;
    } 
    

    我提取了六个内部类来实现一个公共接口、十几个私有方法和一个枚举。结果是减少了500行代码、可忽略的冗余以及在公共方法中只嵌套了6个级别。

    我的经验法则是:

    a)对于超过3的每一级嵌套,重构的概率都会增加 1/3

    b)对于方法中的每个充满代码的屏幕,重构的概率增加1/3。

    c)对于方法中的每一行重复代码,重构的概率增加1/3。

        7
  •  2
  •   BenAlabaster    15 年前

    我尽量不让它变得比这更疯狂(5/6级),有时这是不可避免的。如果我的所有文件都在同一个名称空间中,我将删除名称空间声明,并在项目属性中声明它,这会降低一个级别。

    namespace MyNamespace
    {
      class MyClass
      {
        static void MyMethod()
        {
          try
          {
            if(...)
            {
              for(...)
              {
              }
            }
          }
          finally
          {
          }
        }
      }
    }
    

    在可能的情况下,一种方法应该只用于一件事和一件事。有许多“经验法则”,有些可以100%的时间来工作,但大多数的经验法则虽然可行,但90%的时间不能涵盖每个角度。指导方针就是这样——它们不应该把你限制在你不能完成工作的范围内。

    用你的常识,如果你的代码变得不可读,你就有太多的巢。

    我尽量遵循以下指导原则:

    • 每种方法只能做一件事- Curly's Law .
    • 尽量将代码块中的代码量保持在最小值-我更喜欢将其保持在20行左右,但在100行时,它的边界太长了。
    • 如果代码开始对我不可读,其他人将无法读取,请重构它。
    • 尽量在一个类中保持最小的代码量-1000行在上面,越短越好。
    • 不要牺牲好的编码标准,除非你别无选择,也就是说,你有一个最后期限,你不可能遇到不切几个角。如果您确实需要使用这样的快捷方式,请添加注释,说明您为什么使用该快捷方式,以便下一个开发人员可以看到您为什么这样做。
        8
  •  1
  •   quamrana    15 年前

    我发现这是日常工作,但仅仅是因为继承了代码库。

    在我自己的代码中,我早就重构了,甚至只调用一次方法来表达意图。

        9
  •  1
  •   MRFerocius    15 年前

    尽量避免嵌套,因为它增加了循环的复杂性,为什么不把它们放在类上,或者使用其他策略来代替呢?

    我记得我大学的一个教授说“一个函数,不应该超过7行。”

    我会记住的:)

    希望这能帮上忙!

        10
  •  1
  •   Mark Beckwith    15 年前

    我称之为 “孤立的丑陋。”

    它是 丑陋的 因为开关里面的开关很难看。他们可以通过一些很好的OO技术来避免。但它可以完成任务,并且编码所花的时间更少。

    孤立的 因为最好对其进行编码,为其编写一些测试,然后将其放在一边,再也不要查看它。

    但是,可以。如果你到处都这样做,那可能就不好了。

    我更关心嵌套的大O复杂性 while 声明。

        11
  •  0
  •   Ville    11 年前

    我们在一个大型“业务线”应用程序中有一个代码库,在该应用程序中,嵌套级别可以是15或更多。在有这么多缩进的方法中遵循逻辑流是非常困难的。

    但从历史上看,一个政策是避免在方法中出现多次返回。但事后看来,这似乎是一个非常有成效的设计决策。