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

问题描述 投票:1回答:3

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

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()方法的圈复杂度?提前致谢。

java android refactoring switch-statement cyclomatic-complexity
3个回答
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
投票

这是我在早期版本的GWT(Google Web Toolkit)中遇到的问题之一。 GWT是谷歌的答案,为JAVA开发人员提供了一种使用JAVA编写JavaScript代码的方法。

我们开始使用单个匿名内部类来处理网页上的每个事件/元素。当你没有很多元素时,它工作得很好,这对于网页来说是不现实的。因此,随着元素数量的增加,它变得无法管理和混乱。然后我们很快就遇到了你提出的同一个问题。谷歌在更高版本的GWT中使用事件总线解决了这个问题。

这是怎么解决的?他们创建了一个模式,您可以将条件从一个级别抽象到事件总线,并让它调用正确的处理程序。

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

实际上,在我的想法中,你想要做的是完全避免圈复杂度模式,就像我通过事件总线或事件处理程序或映射抽象一个级别一样,最终调用一个函数来避免代码重复并用另一个解决这个问题图案。

我宁愿创建更多的小函数,因此使代码更像组件,而不是让if / else模式继续自我复制。我发现,一旦你沿着那条路走下去,模式没有尽头,你将继续被迫添加更多的if / else语句,直到你用更好的解决方案重构代码。

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

以下是Cyclomatic Complexity Refactoring Tips的一些很好的技巧,有很好的代码示例。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.