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

oug3syen  于 2021-06-27  发布在  Java
关注(0)|答案(3)|浏览(401)

我有一个布尔标志,我想基于它执行一行功能,比如增加一个变量或调用一个对象的方法等等。在Java8中,用最小的认知复杂度来实现这一点的最佳方法是什么?

// 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中,有没有更简单的方法来降低认知复杂性?当我面对这个sonarlint规则的问题时:方法的认知复杂性不应该太高,如果else语句太多

cx6n0qe3

cx6n0qe31#


我的代码如下所示:

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
        }
    }
}

所有这些都增加了认知的复杂性

falq053o

falq053o3#

回答你的具体例子:
因为一切只取决于 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 list) {
for (SomeClass a : list) {
a.doIt();
}
}

或者被改写成

void myMethod(List list) {
list.forEach(SomeClass::doIt);
}

如果你喜欢的话,那主要是风格/个人喜好的问题。
从那时起,您就可以开始考虑拆分以 `1` 以及 `2` 分离战略对象。
还要注意,我们是如何突然只从外部使用一个方法的-这可以用来减少的公共接口 `SomeClass` ,作为具体的例子,我们只需要 `doIt()` 公开。这是一个通常被称为“说,不问”的原则的应用。避免询问对象字段的内容,以便根据这些值做出决策。相反,告诉他们你想发生什么,把细节留给他们。

相关问题