对多个字段进行空验证的最佳实践

时间:2016-10-17 10:36:12

标签: php

我的计划中有一个时刻我达到了以下条件:

if ($Student->getClass() != null) {
    if ($Student>getClass()->isActive()) {
        if ($Student->getClass()->getAcceptedGrades() != null) {
            if (in_array($StudentGrade, $Student->getClass()->getAcceptedGrades())) { 
                echo "The student has a acceptable grade."
            }
        }
    }
}

我问自己是否没有更好的方法来进行这种验证。

我无法尝试验证null对象中的值,因此我总是需要验证是否有我正在访问的对象。

2 个答案:

答案 0 :(得分:2)

只要你的方法返回null,你就会进行这些检查。

您可以使用此PHP port of java.util.Optional,但这仍然需要您到处检查。虽然看起来好一点。

But the real issue is really returning null。例如,你的

$Student->getClass()->getAcceptedGrades()  

显然会返回nullarray。如果该方法总是返回一个空数组而不是null,则可以在调用in_array之前删除空检查。一般来说,一个方法返回一个东西而只返回那个东西是一个好习惯。这可以防止在必须检查返回值时使用代码。

如果您将getAcceptedGrades更改为始终返回数组,则会留下

if ($Student->getClass() != null) {
    if ($Student>getClass()->isActive()) {
        if (in_array($StudentGrade, $Student->getClass()->getAcceptedGrades())) { 
            echo "The student has an acceptable grade."
        }
    }
}

正如您所看到的,所有if检查基本上都在getClass次返回时运行。我认为,它是一个Class / Course对象。关于它的坏处是,包含这些if检查的代码知道验证可接受等级的条件。相反,Course对象应该是专家,因为它包含它的信息。那么为什么不只是在Course对象中添加方法hasAcceptableGrade()呢?

public function hasAcceptableGrade($StudentGrade)
{
    return $this->isActive()
        && in_array($StudentGrade, $this->getAcceptedGrades());
}

这样,具有if检查的代码不需要知道如何计算接受等级的详细信息。相反,它只是询问Course对象,它将为您留下

if ($Student->getClass() != null) {
    if ($Student->getClass()->hasAcceptableGrade($StudentGrade) {
        echo "The student has an acceptable grade."
    }
}

要删除最终的空检查,您将再次确保始终返回Class / Course对象。如果无法做到这一点,因为学生没有注册,要么getClass提出StudentNotEnrolled例外并将代码更改为

try {
    if ($Student->getClass()->hasAcceptableGrade($StudentGrade) {
        echo "The student has an acceptable grade."
    }
} catch (StudentNotEnrolledException $e) {
    echo "Student is not enrolled"
}

或为此案例引入Null Object,例如

class NullCourse
{
    public function hasAcceptableGrade($StudentGrade)
    {
        return false;
    }    
}

我们总是在这里返回假,因为我们假设一个没有课程的学生将永远不会有一个可接受的课程成绩。如果你不想遵循这个逻辑,你可以明显地改变它,或者在这里提升StudentNotEnrolledException

如果返回值为false,则会将代码缩减为

if ($Student->getClass()->hasAcceptableGrade($StudentGrade) {
    echo "The student has an acceptable grade."
}

现在唯一剩下的就是将hasAccetableGrade方法移动到Student对象上,这样您的消费代码就可以简单地询问Student对象,而不是知道它首先需要获取Course对象。我省略了这个示例代码。你最终会

if ($Student->hasAcceptableGrade($StudentGrade) {
    echo "The student has an acceptable grade."
}

只有一个。没有多重条件。没有空的检查。

答案 1 :(得分:0)

将一个能为您完成这项工作的功能纳入学生班。

class Student {
    public function hasEmptyClass() {
        $class = $this->getClass();
        if (! $class instanceof Class || ! $class->hasAcceptableGrade(...)) {
            return true;
        }
        return false;
    }
}