本文目录导读:

- 创建目录结构
- 定义接口(契约)
- 实现接口
- 创建基础 Repository 类(可选)
- 注册服务提供者
- 在 config/app.php 中注册服务提供者
- 在控制器中使用 Repository
- 高级用法:使用 Laravel 自动绑定
- 使用 Repository 与缓存(进阶)
- 优势
- 注意事项
Laravel 中的规约模式(Repository Pattern)是一种常见的设计模式,用于将数据访问逻辑与业务逻辑分离,以下是详细的实现步骤:
创建目录结构
app/
├── Repositories/
│ ├── Contracts/
│ │ └── UserRepositoryInterface.php
│ └── UserRepository.php
└── Providers/
└── RepositoryServiceProvider.php
定义接口(契约)
app/Repositories/Contracts/UserRepositoryInterface.php
<?php
namespace App\Repositories\Contracts;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
interface UserRepositoryInterface
{
public function getAll(): Collection;
public function getById(int $id): ?Model;
public function create(array $data): Model;
public function update(int $id, array $data): bool;
public function delete(int $id): bool;
public function paginate(int $perPage = 15): LengthAwarePaginator;
public function findByEmail(string $email): ?Model;
}
实现接口
app/Repositories/UserRepository.php
<?php
namespace App\Repositories;
use App\Models\User;
use App\Repositories\Contracts\UserRepositoryInterface;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
class UserRepository implements UserRepositoryInterface
{
protected $model;
public function __construct(User $model)
{
$this->model = $model;
}
public function getAll(): Collection
{
return $this->model->all();
}
public function getById(int $id): ?Model
{
return $this->model->find($id);
}
public function create(array $data): Model
{
return $this->model->create($data);
}
public function update(int $id, array $data): bool
{
$record = $this->model->find($id);
return $record ? $record->update($data) : false;
}
public function delete(int $id): bool
{
return $this->model->destroy($id);
}
public function paginate(int $perPage = 15): LengthAwarePaginator
{
return $this->model->paginate($perPage);
}
public function findByEmail(string $email): ?Model
{
return $this->model->where('email', $email)->first();
}
// 你可以添加更多自定义方法
public function getActiveUsers(): Collection
{
return $this->model->where('status', 'active')->get();
}
}
创建基础 Repository 类(可选)
app/Repositories/BaseRepository.php
<?php
namespace App\Repositories;
use Illuminate\Database\Eloquent\Model;
abstract class BaseRepository
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function all()
{
return $this->model->all();
}
public function find(int $id)
{
return $this->model->find($id);
}
public function create(array $data)
{
return $this->model->create($data);
}
public function update(int $id, array $data)
{
$record = $this->model->find($id);
if ($record) {
$record->update($data);
return $record;
}
return null;
}
public function delete(int $id)
{
return $this->model->destroy($id);
}
public function paginate(int $perPage = 15)
{
return $this->model->paginate($perPage);
}
public function findByField(string $field, $value)
{
return $this->model->where($field, $value)->first();
}
}
app/Repositories/UserRepository.php(使用基础类)
<?php
namespace App\Repositories;
use App\Models\User;
class UserRepository extends BaseRepository
{
public function __construct(User $model)
{
parent::__construct($model);
}
public function getActiveUsers()
{
return $this->model->where('status', 'active')->get();
}
}
注册服务提供者
app/Providers/RepositoryServiceProvider.php
<?php
namespace App\Providers;
use App\Repositories\Contracts\UserRepositoryInterface;
use App\Repositories\UserRepository;
use Illuminate\Support\ServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
// 如果需要其他 Repository,继续绑定
// $this->app->bind(PostRepositoryInterface::class, PostRepository::class);
}
public function boot(): void
{
//
}
}
在 config/app.php 中注册服务提供者
'providers' => [
// 其他 Service Providers...
App\Providers\RepositoryServiceProvider::class,
],
在控制器中使用 Repository
app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Repositories\Contracts\UserRepositoryInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
protected $userRepository;
public function __construct(UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
public function index()
{
$users = $this->userRepository->paginate(10);
return view('users.index', compact('users'));
}
public function show($id)
{
$user = $this->userRepository->getById($id);
if (!$user) {
return redirect()->route('users.index')->with('error', 'User not found');
}
return view('users.show', compact('user'));
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
]);
$user = $this->userRepository->create($validated);
return redirect()->route('users.index')->with('success', 'User created successfully');
}
public function update(Request $request, $id)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email,' . $id,
]);
$updated = $this->userRepository->update($id, $validated);
if ($updated) {
return redirect()->route('users.index')->with('success', 'User updated successfully');
}
return redirect()->route('users.index')->with('error', 'User not found');
}
public function destroy($id)
{
$deleted = $this->userRepository->delete($id);
if ($deleted) {
return redirect()->route('users.index')->with('success', 'User deleted successfully');
}
return redirect()->route('users.index')->with('error', 'User not found');
}
}
高级用法:使用 Laravel 自动绑定
你可以在 AppServiceProvider 中添加自动绑定:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(
'App\Repositories\Contracts\UserRepositoryInterface',
'App\Repositories\UserRepository'
);
}
public function boot(): void
{
//
}
}
使用 Repository 与缓存(进阶)
app/Repositories/UserRepository.php(带缓存)
<?php
namespace App\Repositories;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
class UserRepository extends BaseRepository
{
public function __construct(User $model)
{
parent::__construct($model);
}
public function find(int $id)
{
return Cache::remember("user_{$id}", 3600, function () use ($id) {
return parent::find($id);
});
}
public function update(int $id, array $data)
{
Cache::forget("user_{$id}");
return parent::update($id, $data);
}
public function delete(int $id)
{
Cache::forget("user_{$id}");
return parent::delete($id);
}
}
优势
- 松耦合:业务逻辑与数据访问层分离
- 可测试性:可以轻松 mock Repository 进行单元测试
- 可维护性:数据访问逻辑集中管理
- 灵活性:可以轻松更换数据源(如从 MySQL 切换到 MongoDB)
注意事项
- 不要过度使用,对于简单的 CRUD 操作可能增加不必要的复杂性
- 保持 Repository 的单一职责
- 考虑使用 Laravel 的 Eloquent ORM 原生功能,Repository 模式在大型项目中更适用
这样你就实现了 Laravel 的规约模式,使得代码更加清晰、可维护和可测试。