【问题标题】:Laravel - Repository Pattern issuesLaravel - 存储库模式问题
【发布时间】:2015-01-22 16:44:54
【问题描述】:

我的 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,也不必添加任何其他需要这样做的存储库(很多)。

但是,有一个存储库确实具有更新功能,但我希望它做一些“自定义”的事情。假设它是用户存储库:

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).

为什么会这样,我的界面肯定指定了声明应该是什么?

【问题讨论】:

    标签: php laravel repository-pattern


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2014-09-19
        • 1970-01-01
        • 2013-11-26
        • 2014-07-27
        • 2014-03-05
        • 2014-03-15
        • 2016-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多