什么';在Java8中,基于布尔标志执行单行功能的最佳方法是什么?

什么';在Java8中,基于布尔标志执行单行功能的最佳方法是什么?,java,java-8,sonarqube,sonarlint,Java,Java 8,Sonarqube,Sonarlint,我有一个布尔标志,我想根据它执行一行功能,比如增加一个变量或调用一个对象的方法等。在java 8中,用min认知复杂性实现这一点的最佳方法是什么 // Objects a is initialized; // int x, y; // boolean flag; if (flag) { a.doSomething1(); } else { a.doSomethingElse1(); } // want to check multiple times like this if (

我有一个布尔标志,我想根据它执行一行功能,比如增加一个变量或调用一个对象的方法等。在java 8中,用min认知复杂性实现这一点的最佳方法是什么

// Objects a is initialized;
// int x, y;
// boolean flag;
if (flag) {
    a.doSomething1();
} else {
    a.doSomethingElse1();
}

// want to check multiple times like this
if (flag) {
    a.doSomething2();
} else {
    a.doSomethingElse2();
}

if (flag) {
    x++;
} else {
    y++;
}
在Java8中,是否有一种更简单的方法通过降低认知复杂性来实现这些功能?当我面对Sonarint规则的问题时:方法的认知复杂性不应该太高,如果else语句太多

----------编辑-----------------

我的代码如下所示:

void myMethod(List<SomeClass> list) {
    for (SomeClass a : list) {
        SomeClass a;
        String name = a.getName();
        boolean flag = a.getFlag();
        switch(name) {
            case "name1":
                if (flag) a.doSomething1() else a.doSomethingElse1();
                break;
            case "name2":
                if (flag) a.doSomething2() else a.doSomethingElse2();
                break;
            //.... similar otherCases
        }
    }
} 
void myMethod(列表){
对于(a类:列表){
甲级;
字符串名称=a.getName();
布尔标志=a.getFlag();
交换机(名称){
案例“名称1”:
如果(标记)a.doSomething1(),否则a.doSomethingElse1();
打破
案例“名称2”:
如果(标记)a.doSomething2(),否则a.doSomethingElse2();
打破
//……类似的情况
}
}
} 

所有这些都增加了认知的复杂性来回答你的具体例子:

由于一切只取决于
SomeClass
的成员,因此逻辑也应该是此类的一部分。一种方法是:

abstract class SomeClass {               

    public void doIt() {
        String name = this.getName();
        switch (name) {
        case "name1":
            this.doName1();
            break;
        case "name2":
            this.doName2();
            break;
        }
    }
    
    private void doName1() {
        if (this.getFlag())
            this.doSomething1();
        else
            this.doSomethingElse1();
    }

    private void doName2() {
        if (this.getFlag())
            this.doSomething2();
        else
            this.doSomethingElse2();
    }
    
    abstract protected String getName();

    abstract protected boolean getFlag();

    abstract protected void doSomething1();

    abstract protected void doSomething2();

    abstract protected void doSomethingElse1();

    abstract protected void doSomethingElse2();
}
myMethod
可以是

void myMethod(List<SomeClass> list) {
    for (SomeClass a : list) {
        a.doIt();
    }
}
void myMethod(列表){
对于(a类:列表){
a、 doIt();
}
}
或者被改写为

void myMethod(List<SomeClass> list) {
    list.forEach(SomeClass::doIt);
}
void myMethod(列表){
list.forEach(SomeClass::doIt);
}
如果你喜欢,但这主要是风格/个人偏好的问题


从那时开始,您可以开始考虑用<代码> 1 和<代码> 2 > /代码>对策略对象进行拆分。


还要注意我们是如何突然只从外部使用一个方法的-这可以用来减少
SomeClass
的公共接口,对于具体的示例,我们只需要
doIt()
是公共的。这是一个经常被称为“告诉,不要问”的原则的应用。避免询问对象字段的内容,以便根据这些值做出决策。相反,告诉他们你想发生什么,把细节留给他们。

只要把所有的东西都放在同一个
if
else
中即可。还是你在问别的问题?我不知道我是否明白你想在这里简化什么
if(a)b else c
已经很短了。如果你想这样做,if(flag)x++else y++就不能解决我的问题,因为它仍然会通过任何嵌套因子增加sonar lint的认知复杂性-一般来说,如果有一个包含非平凡逻辑的循环,那么将主体提取到另一个函数。这也有助于遵守其他规则,例如有限的嵌套级别。如果您有多个布尔标志,则可以提取相等的部分和不同的部分,并使用模板方法或策略模式等模式。但选择哪一个取决于多个因素,一般来说无法回答。继续@Hulk的评论-注意您编辑的示例如何从
a
中提取数据,然后使用数据来决定要做什么。这种行为应该在
SomeClass
本身中。另见:告诉,不要问