替代条件逻辑的嵌套 if

Alternative to nested if for conditional logic

是否有一种设计模式或方法或语言可以让您编写复杂的条件逻辑而不仅仅是嵌套的 If?

最起码,这样的问题有名字吗?我无法在这里或通过 Google 找到任何描述我试图解决的问题的内容,而不仅仅是用 Switch 语句替换您的 IF。

我正在使用一个脚本来生成一堆数据。作为其中的一部分,我想添加很多分支条件逻辑,这些逻辑应该提供多样性并阻止某些组合。

类似于,如果用户属于 A 组,则他们不能属于 B 组,如果他们具有属性 C,则将他们限制为特征 5 或 6,但不能低于或高于该特征.

答案很简单:重构。

举个例子(伪代码):

if (a) {
    if (b) {
        if (c) {
             // do something
        }
    }
}

可以替换为:

if (a && b && c) {
    // do something
}

现在,假设 abc 是复杂的谓词,这使得代码难以阅读,例如:

if (visitorIsInActiveTestCell(visitor) &&
    !specialOptOutConditionsApply(request, visitor) &&
    whatEverWeWantToCheckHere(bla, blabla)) {
    // do something
}

我们也可以重构它并创建一个新方法:

def shouldDoSomething(request, visitor, bla, blabla) {
    return visitorIsInActiveTestCell(visitor) &&
        !specialOptOutConditionsApply(request, visitor) &&
        whatEverWeWantToCheckHere(bla, blabla)
}

现在我们的 if 条件没有嵌套并且更容易阅读和理解:

if (shouldDoSomething(request, visitor, bla, blabla)) {
    // do something
}

有时提取这样的逻辑并重构并不简单,可能需要花一些时间来考虑,但我还没有运行成一个不可能的例子。

假设您使用的是面向对象的语言,您可能想用 polymorphism 替换条件逻辑。

也就是说,而不是:

class Bird:
    #...
    def getSpeed(self):
        if self.type == EUROPEAN:
            return self.getBaseSpeed();
        elif self.type == AFRICAN:
            return self.getBaseSpeed() - self.getLoadFactor() * self.numberOfCoconuts;
        elif self.type == NORWEGIAN_BLUE:
            return 0 if isNailed else self.getBaseSpeed(self.voltage)
        else:
            raise Exception("Should be unreachable")

你可以说:

class Bird:
    #...
    def getSpeed(self):
        pass

class European(Bird):

    def getSpeed(self):
        return self.getBaseSpeed()


class African(Bird):

    def getSpeed(self):
        return self.getBaseSpeed() - self.getLoadFactor() * self.numberOfCoconuts


class NorwegianBlue(Bird):

    def getSpeed():
        return 0 if self.isNailed else self.getBaseSpeed(self.voltage)

# Somewhere in client code
speed = bird.getSpeed()

摘自 here.

上述所有答案似乎都遗漏了问题。 硬件接口中经常出现的模式之一如下所示:

if (something) {
  step1;
  if ( the result of step1) {
    step2;
     if (the result of step2) {
       step3;
     ... and so on
}}}...

这个结构不能折叠成逻辑合取,因为每一步都依赖于前一步的结果,并且本身可能有内部条件。

在汇编代码中,测试和分支到一个共同的目标是一件简单的事情;即,可怕的 "go to"。在 C 中,您最终得到一堆缩进代码,大约 8 级后很难阅读。

我能想到的最好的是:

while( true) {
  if ( !something)
    break;
  step1
  if ( ! result of step1)
    break;
  step2
  if ( ! result of step2)
    break;
  step3
  ...
  break;
}

有没有人有更好的解决方案?