想象下面的抽象接口
interface IDomainRepository {
/**
* Finds a Domain Object by the Id
*
* @param int $id the id of the object
*
* @return IDomainObject the domain object
*/
public function findById($id);
//More than that method...
}
现在是一个特定的接口,从IDomainRepository
扩展interface IUserRepository extends IDomainRepository {
//More than only extending...
}
如果我调用这样的东西,我希望在这里键入提示而不附加注释(因为我经常使用这个)。
function foo(IUserRepository $repo) {
$user = $repo->findById(42)
//Typehint User without @var User $user
}
目前我是这样做的:
/**
* Interface IUserRepository
* @method User findById($id)
*/
interface IUserRepository extends {
}
但是"@method"参数是用于隐藏的魔术方法的。所以这感觉不对。有没有更好的解决方案?
我不应该有一个基本接口,只有一个特定的(这意味着复制&粘贴大约20个方法签名?
由于PHP中没有返回类型提示,但大多数情况下都是关于首选项的,因此根据所使用的IDE,使用@method
标记或docblock进行额外的方法声明可能没有区别,因此....
请注意,您不一定要移动方法(并且您很可能不想无论如何,因为它将使IDomainRepository
的实现不需要findById()
方法),但您可以简单地在必要时在扩展接口中重新声明/覆盖它们,并提供适当的docblock,如@Deele:
interface IUserRepository extends IDomainRepository {
/**
* Finds a User by Id
*
* @param int $id the id of the object
*
* @return IUserRepository the User object
*/
public function findById($id);
}
我个人认为使用@method
更干净的方法,因为它使findById()
的具体实现更清楚应该如何行为(通过查看方法声明的代码),并且它预计与基本接口之一不同。
// Covariant return-type:
interface Collection {
function map(callable $fn): Collection;
}
interface Set extends Collection {
function map(callable $fn): Set;
}
恐怕没有办法做到这一点,因为PHPDoc代码中没有内置这样的深度。
我能想到的唯一节省行数的方法是在您的User
类中重复相同的findById()
方法,并使其仅调用父方法findById()
并添加修改后的@return
注释,如
interface IUserRepository extends IDomainRepository {
/**
* @see IDomainRepository::findById()
*
* @param int $id the id of the object
*
* @return IUserRepository the User object
*/
public function findById($id) {
return parent::findById($id);
}
}
PS: findById()
按我对OOP逻辑的理解应该是静态函数
我有一个类似的问题,也许static
或$this
作为返回类型可能是你的东西。
背后的思想是指晚期静态绑定
interface IDomainRepository
{
/**
* @param int $id the id of the object
*
* @return static the domain object
*/
public function findById($id);
}
interface IUserRepository extends IDomainRepository
{
/**
* @param string $name
*
* @return static
*/
public function findUserByName($name);
}
function foo(IUserRepository $repo)
{
$user = $repo->findById(42);
$user->find... // suggestions by PHPStorm: findById and findUserByName
}