Laravel规约模式怎么实现

wen PHP项目 1

本文目录导读:

Laravel规约模式怎么实现

  1. 创建目录结构
  2. 定义接口(契约)
  3. 实现接口
  4. 创建基础 Repository 类(可选)
  5. 注册服务提供者
  6. 在 config/app.php 中注册服务提供者
  7. 在控制器中使用 Repository
  8. 高级用法:使用 Laravel 自动绑定
  9. 使用 Repository 与缓存(进阶)
  10. 优势
  11. 注意事项

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);
    }
}

优势

  1. 松耦合:业务逻辑与数据访问层分离
  2. 可测试性:可以轻松 mock Repository 进行单元测试
  3. 可维护性:数据访问逻辑集中管理
  4. 灵活性:可以轻松更换数据源(如从 MySQL 切换到 MongoDB)

注意事项

  • 不要过度使用,对于简单的 CRUD 操作可能增加不必要的复杂性
  • 保持 Repository 的单一职责
  • 考虑使用 Laravel 的 Eloquent ORM 原生功能,Repository 模式在大型项目中更适用

这样你就实现了 Laravel 的规约模式,使得代码更加清晰、可维护和可测试。

抱歉,评论功能暂时关闭!