2

我有一个很长的 if 条件如下。有两个条件都必须不满足,才能评估语句。我确实将它作为一个带有很多 && 和 !但它变得不可读。我尝试将它拆分为一个if elsif else,它更具可读性但读起来不太好,因为第一个if elsif块中没有代码。

整理此代码块的最佳做法是什么?

if ($instructionObject->instruction=='nesting_grammar' && $instructionObject->match=='>'){ //if instruction is a '>' child indicator
   //don't change the child depth
}else if ($instructionObject->instruction=='selector' && is_object($this->instructions[$key+1]) && $this->instructions[$key+1]->instruction == 'nesting_grammar' && $this->instructions[$key+1]->match == '>'){ //if instruction is a selector followed by a '>'
   //don't change the child depth
}else{
   $insertOffset += $childDepth;
   unset($childDepth);
}
4

5 回答 5

3

您可以使用“提取方法”重构。将您的条件替换为新方法。

if ($this->isInstructionNestingGrammar($instructionObject)){ 
   //don't change the child depth
}else if ($this->isIntructionSelect($instructionObject)){ 
   //don't change the child depth
}else{
   $insertOffset += $childDepth;
   unset($childDepth);
}

在新方法中,将每个比较放在单独的行中。

PS 不要害怕方法名称太长。

于 2013-04-17T00:17:12.353 回答
1

不是直接回答你的问题,而是像这样的:

if (my_check($instructionObject) || $instructionObject->instruction=='selector' && my_check($this->instructions[$key+1])) {
} else {
   $insertOffset += $childDepth;
   unset($childDepth);
}

function my_check($obj) {
    return is_object($obj) && $obj->instruction == 'nesting_grammar' && $obj->match == '>';
}

——你基本上做了两次同样的事情,是时候考虑一​​个函数了。

于 2013-04-17T00:11:06.500 回答
1

只需否定条件并跳过ifandelse if部分,因为两个初始条件不做任何事情......

if (
     !($instructionObject->instruction=='nesting_grammar' && 
       $instructionObject->match=='>') 
    || !($instructionObject->instruction=='selector' 
        && is_object($this->instructions[$key+1]) 
        && $this->instructions[$key+1]->instruction == 'nesting_grammar' 
        && $this->instructions[$key+1]->match == '>')
 ) {
   $insertOffset += $childDepth;
   unset($childDepth);
 }
于 2013-04-17T00:05:56.543 回答
0

将子表达式拉出到变量中。伪示例:

flibjit = FlibjitManager.FlibjitInstance(this);
isFrob = 
    (flibjit.Froblocity >= FlibjitManager.FrobThreshold) &&   
    (flibjit.Type == FlibjitTypes.Frobby);

if (isFrob) {
   // ...
于 2013-04-17T00:12:08.337 回答
0

就我个人而言,如果我要跨越多行检查,我将其布局类似于我布局 JavaScript 对象的方式;

if (
    great big long check line goes in here &&
    another really long ugly check line goes in here too
) {
   // Do this code
}
else if (
    check 3 &&
    check 4
) {
    //Do this code
}
于 2013-04-17T00:06:27.573 回答