使用开关盒按类型创建不同的对象


Create different object by type using switch-case?

每个人都有美好的一天,

我们使用很多语句,如if-else或switch-case,根据不同的条件创建不同的对象,例如:

interface Job {
    public function do();
}
class Auto implement Job {
    ...
}
class Month implement Job {
    ...
}
...
// another script to run jobs
...
switch($type) {
    case 'auto':
        $instance = new Auto();
        break;
    case 'month':
        $instance = new Month();
        break;
    default:
        throw new Exception('not support type!');
}
$instance->do();

问题是,如果我们使用 if-else/switch-case 使代码随着越来越多的类型而快速增长。
我们可以使用反射或动态实例启动,但是IDE(如PHPStorm)将无法找到类的用法。
有没有更好的方法来反对使用开关盒?

真的有两个答案。

您应该键入提示$instance作为界面Job。这就是 OOP 中Interface的全部目的。您可以通过以下方式执行此操作:

switch ($type) {
    case 'auto':
        $instance = new Auto();
        break;
    // ...
}
/** @var 'Job $instance */
$instance->do();

如果你想走这条路,你可以向 PHPStorm 提供元数据,用于类型提示工厂方法。元数据文件可以提交到源代码管理,就像代码一样 https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata