如何降低Cyclomatic Complexity?

时间:2011-05-02 03:59:59

标签: java refactoring instanceof cyclomatic-complexity

我有一个接收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...
                }
            }
        }
    }
}

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

5 个答案:

答案 0 :(得分:39)

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

答案 1 :(得分:28)

圈复杂度是基于代码图结构的度量。具体而言,它基于通过代码的可能路径的数量;有关详细信息,请参阅here。虽然CC与典型程序员所看到的代码复杂性之间存在相关性,但它们并不相同。例如:

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

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

你可以说CC与真实代码复杂性之间的关系就像是智商和真实情报之间的关系。

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


在这个特定的例子中,高CC测量值不会导致典型程序员遇到任何困难。最好的答案(IMO)是单独留下方法。把它弄成假阳性。

答案 2 :(得分: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();
}

答案 3 :(得分:-1)

为什么需要降低复杂性?这是一个足够简单的模式,任何有能力的开发人员都会认为它是一个微不足道的功能。

我可能会这样写

    if (object instanceof ObjectTypeA) 
    {
        doSomethingA();
    }
    else if (object instanceof ObjectTypeB) 
    {
        doSomethingB();
    }
    else if (object instanceof ObjectTypeC) 
    {
        doSomethingC();
    }

如果要满足“CC必须小于x”的一些深奥需求,那么标准在那里确保可维护代码的总体规则意味着无论CC有多高,这都是可以接受的。

答案 4 :(得分:-2)

从来没有达到“降低圈复杂度”的目标,尽管有时候我被LOC付了钱。

你的代码“足够好”。我的眼睛绊倒在括号上,所以我牺牲了一点性能并做了以下(提供类型A,B等不在同一层次结构中):

receive(Object object) {
    if (object intanceof ObjectTypeA) doSomethingA();
    if (object instanceof ObjectTypeB) doSomethingB();
    ...

或(如果它们在同一层次结构中):

receive(Object object) {
    if (object intanceof ObjectTypeA) { doSomethingA(); return; }
    if (object instanceof ObjectTypeB) { doSomethingB(); return; }
    ...

不知道它是否会减少圈中性物质,并且不在乎。