假设我正在 Laravel 中创建一个存储库模式,并且我有一个 UserRepositoryEloquent 类。我还想要一个 PostRepositoryEloquent 类,它们将共享很多方法(find、findAll、findOrFail 等)。所以我将这些方法放在抽象的 BaseRepositoryEloquent 类中。这些方法之前会返回 UserInterface 和 PostInterface,但现在它们都会返回 Laravel 抽象模型类。
每个存储库也在实现它们的接口,例如UserRepositoryEloquent 和 UserRepositoryFileStorage 都实现了 UserRepositoryInterface,这迫使它们都实现自己的“查找”方法,只要它们都返回 UserInterface 的类型,但现在情况已不再如此,因为 UserRepositoryEloquent 继承了这些方法,正在返回模型;因此我现在得到错误:
Declaration of UserRepositoryEloquent->find(id) must be compatible with UserRepositoryInterface->find(id)
用于文件存储的用户存储库
<?php
class UserRepositoryFileStorage implements UserRepositoryInterface
{
public function find(int $id): ?UserInterface
{
// fetch from file storage
}
}
DB Eloquent 的用户存储库
<?php
class UserRepositoryEloquent extends BaseRepositoryEloquent implements UserRepositoryInterface
{
// inherits 'find' from BaseRepositoryEloquent which returns type Model, not UserInterface
}
例如 Eloquent 的 Post Repository
<?php
class PostRepositoryEloquent extends BaseRepositoryEloquent implements PostRepositoryInterface
{
// eloquent-post-specific methods
}
<?php
abstract class BaseRepositoryEloquent
{
public function __construct(private Model $model) {}
public function find(int $id): ?Model
{
return $this->model->find($id);
}
}
强制所有用户存储库实现“查找”方法的接口
<?php
interface UserRepositoryInterface
{
public function find(int $id): UserInterface;
}
<?php
# Laravel Model Class
class User extends Model implements UserInterface
{
public function getId(): int
{
return $this->getAttribute('id');
}
}
<?php
# Example just to show interface used for typehinting User entities
interface UserInterface
{
public function getId(): int;
}
尝试了很长时间的思考,但除了删除类型提示之外,目前还没有想出解决办法。