将switch语句重构为多态代码

时间:2017-06-10 10:53:33

标签: php laravel refactoring

我想删除switch statementm但我真的不知道怎么做。

/**
 * @return TreeGenerable
 */
public function chooseGenerationStrategy()
{
    switch (true) {
        case $this->isDirectEliminationCompetitor():
            $generation = new DirectEliminationCompetitorTreeGen($this, null);
            break;
        case $this->isDirectEliminationTeam():
            $generation = new DirectEliminationTeamTreeGen($this, null);
            break;
        case $this->isPlayoffCompetitor():
            $generation = new PlayOffCompetitorTreeGen($this, null);
            break;
        case $this->isPlayoffTeam():
            $generation = new PlayOffTeamTreeGen($this, null);
            break;
        default:
            $generation = new PlayOffCompetitorTreeGen($this, null);
    }
    return $generation;
}

isDirectEliminationCompetitor这样的所有方法都是这样的条件:

public function isDirectEliminationCompetitor()
{
    return !$this->category->isTeam() && $this->isDirectEliminationType() && !$this->hasPreliminary();
}

任何想法我应该如何提高这种方法的复杂性?

1 个答案:

答案 0 :(得分:2)

查看cyclomatic and npath complexity,您当前的方法非常低,两者的复杂度均为5。

更改使用if语句的方法,圈复杂度保持在5但npath复杂度最高为16:

/**
 * @return TreeGenerable
 */
public function chooseGenerationStrategy()
{
    if ($this->isDirectEliminationCompetitor()) {
        return new DirectEliminationCompetitorTreeGen($this, null);
    }

    if ($this->isDirectEliminationTeam()) {
        return new DirectEliminationTeamTreeGen($this, null);
    }

    if ($this->isPlayoffCompetitor()) {
        return new PlayOffCompetitorTreeGen($this, null);
    }

    if ($this->isPlayoffTeam()) {
        return new PlayOffTeamTreeGen($this, null);
    }

    return new PlayOffCompetitorTreeGen($this, null);
}

使用elseif而不是if语句将它们都降低到5,这也使它更难以读取:

/**
 * @return TreeGenerable
 */
public function chooseGenerationStrategy()
{
    if ($this->isDirectEliminationCompetitor()) {
        return new DirectEliminationCompetitorTreeGen($this, null);
    } elseif ($this->isDirectEliminationTeam()) {
        return new DirectEliminationTeamTreeGen($this, null);
    } elseif ($this->isPlayoffCompetitor()) {
        return new PlayOffCompetitorTreeGen($this, null);
    } elseif ($this->isPlayoffTeam()) {
        return new PlayOffTeamTreeGen($this, null);
    } else {
        return new PlayOffCompetitorTreeGen($this, null);
    }
}

您可以对此方法进行的唯一简化是删除default个案并返回而不是将结果赋值给变量:

/**
 * @return TreeGenerable
 */
public function chooseGenerationStrategy()
{
    switch (true) {
        case $this->isDirectEliminationCompetitor():
            return new DirectEliminationCompetitorTreeGen($this, null);
            break;
        case $this->isDirectEliminationTeam():
            return new DirectEliminationTeamTreeGen($this, null);
            break;
        case $this->isPlayoffCompetitor():
            return new PlayOffCompetitorTreeGen($this, null);
            break;
        case $this->isPlayoffTeam():
            return new PlayOffTeamTreeGen($this, null);
            break;
    }

    return new PlayOffCompetitorTreeGen($this, null);
}

这使得圈复杂度保持为5,但将npath复杂度降低到4。

所以看起来你现在的方法几乎是最有效的,尽管它可能看起来不是最好或最漂亮。