如何减少onClick()方法中的圈复杂度

时间:2013-02-01 13:48:59

标签: java android refactoring switch-statement cyclomatic-complexity

让我们想象一个简单的结构:

public void onClick(View view) {
    switch (view.getId()) {
        case R.id.btn_first: {
            // some code
        }
            break;
        case R.id.btn_second: {
            // some code
        }
            break;
        case R.id.btn_third: {
            // some code
        }
            break;
        // and so on
    }
}

这是一段处理不同按钮点击的简单代码。但随着按钮数量的增加 - switch块的圈复杂度随之增长。是否有另一种方法来表示此代码构造以减少onClick()方法的圈复杂度?提前谢谢。

3 个答案:

答案 0 :(得分:2)

public void onClick(View view) {
    for (ClickHandler handler : allHandlers()) {
        if (handler.supports(view.getId())) {
            handler.onClick(view);
        }
    }
}

interface ClickHandler {
    boolean supports(int viewId);
    void onClick(View view);
}

为每个分支实施ClickHandler并让allHandlers()构建一个列表。

答案 1 :(得分:1)

这是我在较早版本的GWT(Google Web工具包)中遇到的问题之一。 GWT是Google为Java开发人员提供一种使用JAVA编写JavaScript代码的方法的答案。

我们开始使用单个匿名内部类来处理 网页上的每个事件/元素。当您没有太多元素时,它就可以很好地工作,这对于网页而言并不现实。因此,随着元素数量的增加,它变得难以管理且混乱。然后,我们很快就遇到了您提出的同一问题。 Google通过在更高版本的GWT中使用事件总线解决了该问题。

这是如何解决的??他们创建了一种模式,可以在其中将条件抽象到事件总线的上一层,并让其调用适当的处理程序。

不过,回到您的javascript问题,这里是Handling events for many elements模式的一个很好的简单解释

真的,在我看来,您要做的就是完全避免循环复杂性模式,就像我所说的那样,通过使用事件总线或事件处理程序或映射抽象一个级别,最终调用一个函数来避免代码重复并解决此问题另一个模式的问题。

我宁愿创建更多小的函数,从而使代码更像组件,而不是允许if / else模式继续复制自身。我发现,一旦走到那条路,模式就没有止境,您将继续被迫添加更多的if / else语句,直到用更好的解决方案重构代码为止。

我记得在他们训练的JAVA代码中看到过同样的事情 用于学习JAVA的COBOL开发人员以及保持程序思维方式的人员不断陷入这种模式。我曾经看到一个带有26个条件的switch语句,用于检查单个类型条件。

这里有Cyclomatic Complexity Refactoring Tips的一些好的技巧,并提供了良好的代码示例。

答案 2 :(得分:0)

有可能(例如带有执行程序或某些东西的hashmap),但在我看来,它会使代码质量变差。低圈复杂度对于高质量代码是有利的,但最终目标仍然应该是高质量和可维护的代码,而不是低的圈复杂度。