如何解决使用文档块记录 PHP 中的抽象工厂方法返回类型
这已经被反复询问,但回复有点旧,我有点绝望地希望有所改变,因为“无法完成”的回复。
上下文:
class AbstractBuildObject {}
class Hammer extends AbstractBuildObject{}
class Nail extends AbstractBuildObject{}
class AbstractFactory{
/**
* return $type
*/
public function build1(string $type): AbstractBuiltObject {
return new $type();
}
/**
* return any(AbstractBuiltObject)
*/
public function build2(string $someArg): AbstractBuiltObject {
$type = $this->decideTypeBasedOnArgsAndState($someArg);
return new $type();
}
}
我试图用构建器上方的注释来表示我需要的东西。
return $type
(或者理想情况下 return $type of AbstractBuiltObject
应该暗示在输入参数中指定了返回类型。
在第二种情况下,any(AbstractBuiltObject)
表示可能返回抽象类的任何派生实体。
所以我需要某种注解来实现我描述的效果。这些注释显然不起作用,我只是用它们来说明概念。
我知道有人可能会想使用像 return Hammer|Nail
这样的管道类型连接,但就我而言,每次向项目添加新的具体实现时都应该修改工厂类,这也不够具体在 build1
的情况下,我确切地知道返回类型应该是什么。
所以,简而言之,我需要它至少在 PhpStorm 中工作:
(new AbstractFactory())->build1(Hammer::class)-> // I should have Hammer autocomplete here
(new AbstractFactory())->build2('foo')-> // I should have autocomplete of any concretion of the abstract here
解决方法
关于打破 SOLID 中的 D 的哲学对话,如果您希望这样的事情自动完成仅在 Hammer
上可用的方法:
(new AbstractFactory())->build1(Hammer::class)->
那么您已经承诺专门为 Hammer
类编写此代码块。如果你打算这样做,那么你不妨这样做:
$hammer = (new AbstractFactory())->build1(Hammer::class);
如果你这样做,那么你也可以这样做:
/**
* @var Hammer
*/
$hammer = (new AbstractFactory())->build1(Hammer::class);
然后您在 $hammer->
上的自动完成应该可以工作。
我们采用的解决方案是这样的:
<?php
class AbstractBuiltClass {
/**
* @return static
*/
public static function type(self $instance)
// change return type to :static when #PHP72 support is dropped and remove explicit typecheck
:self
{
if(!($instance instanceof static)){
throw new Exception();
}
return $instance;
}
}
class Hammer extends AbstractBuiltClass{
function hammerMethod(){}
}
Hammer::type($factory->get(Hammer::class))->hammerMethod();
可行解决方案的竞争者:
- Psalm 模板注释:https://psalm.dev/docs/annotating_code/templated_annotations/ 很有前途,但尚未得到广泛支持
- 可变文档块(参见 Alex Howansky's answer)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。