Laravel - 存储库模式问题

时间:2014-11-24 20:46:45

标签: php laravel repository-pattern

我使用存储库模式获得了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;
    }
}

现在,我不必将update()方法添加到我的EloquentServerRepository,也不需要添加其他任何需要执行此操作的存储库(很多)。

但是,有一个存储库确实具有更新功能,但我希望它可以执行某些操作" custom"。让我们说它是用户存储库:

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)

为什么这个,当然我的界面指定了声明应该是什么?

2 个答案:

答案 0 :(得分:1)

您可以通过赋予默认值$ status optional来传递该错误,例如:

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

如果没有它是可选的(默认值),你说这个方法需要有第三个参数,这违反了ServerRepository设置的合同

答案 1 :(得分:0)

这是因为您正在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);
    }
}