繁体   English   中英

Laravel-存储库模式问题

[英]Laravel - Repository Pattern issues

我有使用存储库模式的Laravel应用程序。 我还有一个名为EloquentRepository的抽象类,其中包含基本方法。 我所有的存储库都有一个update()方法,在这里我仅使用ID和数组更新模型:

abstract class EloquentRepository {

    public function update($id, array $array) {
        $this->model->whereId($id)->update($array);
    }

}

现在,我还有一个Server存储库:

interface ServerRepository {

   public function update($id, array $options);

}

class EloquentServerRepository extends EloquentRepository implements ServerRepository {

    protected $model;

    public function __construct(Server $model)
    {
        $this->model = $model;
    }
}

所以现在,我不必向我的EloquentServerRepository添加update()方法,也不必向其他任何需要这样做的Repository添加(很多)。

但是,有一个具有更新功能的存储库,但我希望它执行“自定义”操作。 可以说这是用户存储库:

interface UserRepository {

   public function update($id, array $options, $status);

}

class EloquentUserRepository extends EloquentRepository implements UserRepository {

    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    public function update($id, array $options, $status)
    {
        $this->model->setStatus($status);
        $this->model->whereId($id)->update($options);
    }
}

因此,现在,我的用户存储库要求每次更新都具有状态。

但是,我得到了错误:

Declaration of EloquentUserRepository::update() should be compatible with EloquentRepository::update($id, array $array)

为什么会这样,当然我的接口指定了声明应该是什么?

您可以通过将$ status设置为默认值来使其成为可选值来传递该错误,例如:

public function update($id, array $options, $status = null)

如果没有它是可选的(具有默认值),则说明此方法需要具有第三个参数,这违反了ServerRepository设置的协定

这是因为您正在扩展EloquentUserRepository ,其中具有如下所示的update方法:

public function update($id, array $array) {
    $this->model->whereId($id)->update($array);
}

在这种情况下,您还将实现UserRepository接口,但是根据基类的update方法, update方法具有不同的签名,如下所示:

public function update($id, array $options, $status);

因此,由于您使用了不同的方法签名,因此错误不断增加。 虽然您可以使用如下所示的可选参数来使两种方法的签名相同:

// EloquentUserRepository
public function update($id, array $array, $status = null) {
    $this->model->whereId($id)->update($array);
}

// interface UserRepository
interface UserRepository {
    public function update($id, array $options, $status = null);
}

但是我建议只使用一个接口或抽象类,并针对不同的用例覆盖EloquentUserRepository的方法。 看起来像这样:

abstract class EloquentRepository {
    public function update($id, array $array, $status = null) {
        $this->model->whereId($id)->update($array);
    }
}

// Only extend the EloquentRepository and override the update method
class EloquentUserRepository extends EloquentRepository {

    protected $model;

    public function __construct(User $model)
    {
        $this->model = $model;
    }

    // re-declare the method to override
    public function update($id, array $options, $status = null)
    {
        $this->model->setStatus($status);
        $this->model->whereId($id)->update($options);
    }
}

或稍微更改EloquentRepository ,例如:

abstract class EloquentRepository {

    public function update($id, array $array, $status = null) {

        if(!is_null($status)) {
            $this->model->setStatus($status);
        }

        $this->model->whereId($id)->update($array);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM