Laravel:使用扩展控制器或特征或其他?

Laravel: use extended controller or Traits or something else?

为了维护我的 Laravel 应用程序并避免大量重复代码,我制定了以下解决方案:

基础控制器

class BaseController extends Controller
{ 
    public function get($id){
        return $this->baseService->get($id);
    }

    public function getAll(){
        return $this->baseService->getAll();
    }
}

基础服务

class BaseService
{
    protected $model;

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

    public function get($id){
        return response()->json($this->model->where('id', $id)->first());
    }

    public function getAll()
    {
        return $this->model->get();
    } 
}

我的控制器

class MyController extends BaseController
{
    protected $model;
    protected $baseService;

    public function __construct(){
        $this->model= new Model();
        $this->baseService = new BaseService($this->model);
    }

    /**
     * This controller has all the functionality from BaseController now
     */
}

我想知道这是不是一个好方法。我应该坚持这个还是应该使用不同的方法?我听说过 Traits,但不确定他们是否在做同样的事情。我用的是Laravel 5.5

这是 Trait 的完美用例。特征旨在用于可重用的功能。它们实施起来超级简单,只需几分钟即可更改您已有的内容。

这是一篇关于它们的精彩文章:https://www.conetix.com.au/blog/simple-guide-using-traits-laravel-5

是的,特征用于定期将方法移出控制器。 Laravel 框架使用的一个很好的例子是 ThrottlesLogin 特性。看看https://github.com/laravel/framework/blob/5.5/src/Illuminate/Foundation/Auth/ThrottlesLogins.php#L20 查看方法如何移出控制器但仍可通过使用 use 关键字导入特征来访问。

虽然特征适用于您的用例,但我不会在这里将它们用于您正在寻找的功能。我会使用 存储库模式 。它会更好地分离您的代码并使其更易于重用。

查看 https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/ 了解有关存储库模式的更多信息。基本上,您会将代码分离到一个单独的存储库中,并使用 Laravel 内置的 IoC 将存储库注入到您的控制器中。

我的控制器

class MyController extends Controller
{
   protected $repo; 

   public function __construct(MyRepository $myRepository)
   {
     $this->repo = $myRepository;
   }

   public function index()
   {
      $myStuff = $this->repo->all();
   }

   // you can also inject the repository directly in the controller
   // actions.
   // look at https://laravel.com/docs/5.5/controllers#dependency-injection-and-controllers
   public function other(MyRepository $repo)
   {
       $myStuff = $repo->all();
   }
}