如何在不使用注释的情况下推断动态实例化 class 的类型?
How to infer type of a dynamically instantiated class without using annotations?
我有一个动态配置,我在其中定义了支持的 classes 供使用:
'registeredRequestParameters' => [
SearchParameter::class,
ReturnsParameter::class,
OrderByParameter::class,
RelationsParameter::class
],
所有这些 class 都扩展了一个摘要 class AbstractParameter
。
现在,当我在我正在开发的包中注册它们时,我正在这样做:
foreach ($this->requestParameters as $parameter) {
/**
* @var AbstractParameter $instance
*/
$instance = new $parameter($this->request, $this->builder, $this->configModel);
$instance->appendQuery();
}
这工作正常,但是我需要说 $instance
实际上是一个 AbstractParameter
,否则我的 IDE 不会从那个 class.
有没有不用注释的方法?
使用类型 annotations 绝对没有错。这就是他们在那里的目的。
但我同意适当的类型提示更好更稳健。
但是为此你不能不使用动态实例化。改用抽象工厂。这将使代码更清晰、更灵活、更明确。
abstract class ParameterFactory {
public static parameter($type, $request, $builder, $configModel) : AbstractParameter
{
switch ($type) {
case SearchParameter::class:
return new SearchParameter($request, $builder, $configModel);
case ReturnsParameter::class:
return new ReturnsParameter($request, $builder, $configModel);
case OrderByParameter::class:
return new OrderByParameter($request, $builder, $configModel);
case RelationsParameter::class:
return new OrderByParameter($request, $builder, $configModel);
}
throw new \InvalidArgumentException("Class $type not supported by factory");
}
}
那么你会做:
foreach ($this->requestParameters as $parameter) {
$instance = ParameterFactory::parameter(parameter, $this->request, $this->builder, $this->configModel);
$instance->appendQuery();
}
顺便说一句,我会为此创建一个 ParameterInterface
和类型提示,而不是抽象的 class。
我有一个动态配置,我在其中定义了支持的 classes 供使用:
'registeredRequestParameters' => [
SearchParameter::class,
ReturnsParameter::class,
OrderByParameter::class,
RelationsParameter::class
],
所有这些 class 都扩展了一个摘要 class AbstractParameter
。
现在,当我在我正在开发的包中注册它们时,我正在这样做:
foreach ($this->requestParameters as $parameter) {
/**
* @var AbstractParameter $instance
*/
$instance = new $parameter($this->request, $this->builder, $this->configModel);
$instance->appendQuery();
}
这工作正常,但是我需要说 $instance
实际上是一个 AbstractParameter
,否则我的 IDE 不会从那个 class.
有没有不用注释的方法?
使用类型 annotations 绝对没有错。这就是他们在那里的目的。
但我同意适当的类型提示更好更稳健。
但是为此你不能不使用动态实例化。改用抽象工厂。这将使代码更清晰、更灵活、更明确。
abstract class ParameterFactory {
public static parameter($type, $request, $builder, $configModel) : AbstractParameter
{
switch ($type) {
case SearchParameter::class:
return new SearchParameter($request, $builder, $configModel);
case ReturnsParameter::class:
return new ReturnsParameter($request, $builder, $configModel);
case OrderByParameter::class:
return new OrderByParameter($request, $builder, $configModel);
case RelationsParameter::class:
return new OrderByParameter($request, $builder, $configModel);
}
throw new \InvalidArgumentException("Class $type not supported by factory");
}
}
那么你会做:
foreach ($this->requestParameters as $parameter) {
$instance = ParameterFactory::parameter(parameter, $this->request, $this->builder, $this->configModel);
$instance->appendQuery();
}
顺便说一句,我会为此创建一个 ParameterInterface
和类型提示,而不是抽象的 class。