<?php
namespace App\Http\Controllers;
use App\Repositories\Interfaces\BlogRepositoryInterface;
use App\User;
class BlogController extends Controller
{
private $blogRepository;
public function __construct(BlogRepositoryInterface $blogRepository)
{
$this->blogRepository = $blogRepository;
}
public function index()
{
$blogs = $this->blogRepository->all();
return view('blog')->withBlogs($blogs);
}
public function detail($id)
{
$user = User::find($id);
$blogs = $this->blogRepository->getByUser($user);
return view('blog')->withBlogs($blogs);
}
}
如你所见,控制器中的代码很简短,可读性非常的高。不需要十行代码就可以获取到所需的数据,多亏了 repository ,所有这些逻辑都可以在一行代码中完成。这对单元测试也很好,因为 repository 的方法很容易复用。
repository 设计模式也使更改数据源变得更加容易。在这个例子中,我们使用 MySQL 数据库来检索我们的博客内容。我们使用 Eloquent 来完成查询数据库操作。但是假设我们在某个网站上看到了一个很棒的博客 API,我们想使用这个 API 作为数据源,我们所要做的就是重写 BlogRepository 来调用这个 API 替换 Eloquent 。
RepositoryServiceProvider
我们将注入 BlogController 中的 BlogRepository ,而不是注入 BlogController 中的 BlogRepositoryInterface ,然后让服务容器决定将使用哪个存储库。这将在 AppServiceProvider 的 boot 方法中实现,但我更喜欢为此创建一个新的 provider 来保持整洁。
php artisan make:provider RepositoryServiceProvider
我们为此创建一个新的 provider 的原因是,当您的项目开始发展为大型项目时,结构会变得非常凌乱。设想一下,一个拥有 10 个以上模型的项目,每个模型都有自己的 repository ,你的 AppServiceProvider 可读性将会大大降低。
我们的 RepositoryServiceProvider 会像下面这样:
<?php
namespace App\Providers;
use App\Repositories\BlogRepository;
use App\Repositories\Interfaces\BlogRepositoryInterface;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
BlogRepositoryInterface::class,
BlogRepository::class
);
}
}
留意用另一个 repository 替代 BlogRepository 是多么容易!
不要忘记添加 RepositoryServiceProvider 到 config/app.php 文件的 providers 列表中。完成了这些后我们需要清空缓存:
php artisan config:clear
就是这样
现在你已经成功实现了 repository 设计模式,不是很难吧?
