PHP强制接口实现

时间:2013-03-05 14:11:05

标签: php interface

我的应用程序中有一个SystemInfoFactory类,它有一个getSystemInfo()方法:

/**
 * Returns SystemInfo object based on which OS
 * server uses
 *
 * @return SystemInfoInterface SystemInfo object
 */
public function getSystemInfo()
{
    $os = $this->getOS();

    $systemInfo = null;

    switch ($os) {
        case "Linux":
            $systemInfo = new LinuxInfo();
            break;
        case "Darwin":
            $systemInfo = new OSXInfo();
            break;
        case "Windows":
            $systemInfo = new WindowsInfo();
            break;
    }
    return $systemInfo;
}

因此它根据主机系统选择适当的对象。现在,每个“info类”实现SystemInfo接口(getArchitecture,getCPU等方法),但正如您所见,我的代码中没有任何地方检查返回的对象是否真正实现了接口。在返回之前检查选定的$systemInfo对象是否实现它会被视为“良好实践”吗?它显然不是 required ,但是如果某人扩展了这个应用程序(例如添加了BSD支持)并忘记实现所有方法,那么他可能更难调试。

2 个答案:

答案 0 :(得分:2)

绝对是好习惯。您在docblock中定义了您的方法返回SystemInfo的实例。您的呼叫者应该能够依赖它。这在您的代码中很简单:

/**
 * Returns SystemInfo object based on which OS
 * server uses
 *
 * @return SystemInfoInterface SystemInfo object
 */
public function getSystemInfo()
{
    $os = $this->getOS();

    $systemInfo = null;

    switch ($os) {
        case "Linux":
            $systemInfo = new LinuxInfo();
            break;
        case "Darwin":
            $systemInfo = new OSXInfo();
            break;
        case "Windows":
            $systemInfo = new WindowsInfo();
            break;
        default:
            throw new \RuntimeException('System not supported');
            break;
    }

    if (!$systeminfo instanceof SystemInfo) {
        throw new \RuntimeException('Invalid SystemInfo object returned');
    }

    return $systemInfo;
}

确保您声明您将从此方法调用中抛出异常。这里的例外使得它非常清楚发生了什么,而不是必须追逐一个未定义的方法"稍后在代码中出错。

答案 1 :(得分:1)

我认为,这里的关键字是Duck Typing。对象的接口由其方法和属性定义,而不是由其祖先和实现的接口定义。

看看这个:http://en.wikipedia.org/wiki/Duck_typing

回到PHP:如果你没有检查对象是否实现了你的界面,它是完全有效的并且没有坏的风格。如果代码崩溃,那么类的实现者必须受到指责。如果代码与if ($obj instanceof FancyInterface) {混淆,我会觉得很烦人。