如何降低Cyclomatic Complexity?

Nat*_*han 16 java refactoring cyclomatic-complexity instanceof

我有一个接收Object的方法,并根据它检测到的对象类型做一些事情:

void receive(Object object) {
    if (object instanceof ObjectTypeA) {
        doSomethingA();
    }
    else {
        if (object instanceof ObjectTypeB) {
            doSomethingB();
        }
        else {
            if (object instanceof ObjectTypeC) {
                doSomethingC();
            }
            else {
                if (object instanceof ObjectTypeD) {
                    doSomethingD();
                }
                else {
                    // etc...
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何降低Cyclomatic Complexity?我四处搜索但找不到任何有用的东西.

laz*_*laz 41

你不能利用面向对象的方法吗?创建一个具有该doSomething()方法的接口,然后创建实现所需行为的子类?那么调用object.doSomething()会执行适当的行为吗?

  • 这可行,但如果这只是为了减少圈复杂度,这是不好的.从这个例子看,这似乎是一个听众的回调.通常,对象根据可能的侦听器特定用法不包含一个方法. (4认同)
  • 从圈复杂度的角度来看,我并没有接近它,所以在这个意义上我没有回答这个问题.然而,当我看到许多条件都使用`instanceof`时,我认为应该认真考虑多态,如果没有别的话,那么创建更可维护的代码.无论如何,这就是圈复杂度测量的意义所在. (2认同)
  • @devadvocate:是这样的 - 阅读第二段:"然而,控制程序规模的研究(......)通常不太确定,很多人发现没有显着的相关性......" (2认同)

Ste*_*n C 28

圈复杂度是基于代码的图结构的度量.具体而言,它基于通过代码的可能路径的数量; 请看这里了解更多详情.虽然CC与典型程序员所看到的代码复杂性之间存在相关性,但它们并不相同.例如:

  • CC不考虑代码的语义; 例如,被调用的这种方法是什么,或算法的数学属性.

  • CC不考虑设计和编码模式.因此,对于理解所使用模式的人来说,CC所说的复杂内容可能很简单.

你可以说CC和实际代码复杂性之间的关系就像是IQ和真实智能之间的关系.

因此,应将Cyclomatic Complexity视为代码复杂部分所在的指标......而不是衡量复杂性或代码质量的真实指标.实际上,高度复杂的代码不一定质量差.通常,复杂性是固有的,试图摆脱它只会让事情变得更糟.


在这个特定的例子中,高CC测量不对应于会导致典型程序员任何困难的事情.最好的答案(IMO)是单独留下方法.把它作为假阳性粉笔.


MrC*_*eeJ 9

void receive(ObjectTypeA object) {
        doSomethingA();
}

void receive(ObjectTypeB object) {
        doSomethingB();
}

void receive(ObjectTypeC object) {
        doSomethingC();
}

...

// Your final 'else' method
void receive(Object object) {
        doSomethingZ();
}
Run Code Online (Sandbox Code Playgroud)