در توسعه وب مدرن، ساخت برنامه های کاربردی قابل نگهداری و مقیاس پذیر بسیار مهم است. لاراول، یکی از محبوب ترین فریم ورک های PHP، مجموعه ای قدرتمند از ابزارها را برای دستیابی به این هدف در اختیار توسعه دهندگان قرار می دهد. یکی از این ابزارها دیزاین پترن ریپازیتوری (Repository Design Pattern) است، که یک الگوی طراحی یا دیزاین پترن پذیرفته شده است که استفاده از کد تمیز و سازمان یافته را ترویج می کند.
در این مقاله به بررسی دیزاین پترن ریپازیتوری و پیاده سازی آن در لاراول می پردازیم. ما مزایای استفاده از repository ها را بررسی خواهیم کرد، ساختار آنها را درک خواهیم کرد و یاد خواهیم گرفت که چگونه از آنها برای ایجاد برنامه های کاربردی قوی و انعطاف پذیر استفاده کنیم.
دیزاین پترن ریپازیتوری یک الگوی ساختاری است که به عنوان یک واسطه بین لایه دسترسی به داده های برنامه (معمولا پایگاه داده) و بقیه برنامه عمل می کند. هدف اصلی آن جداسازی منطق پایداری داده است و به توسعهدهندگان اجازه میدهد بین منابع داده مختلف جابجا شوند، بدون اینکه بر بقیه کد برنامه تاثیر بگذارند.
در لاراول، repository ها اغلب برای کپسوله کردن کوئری های پایگاه داده و ارائه یک لایه اضافی از انتزاع استفاده می شوند. این جداسازی نگرانیها، قابلیت نگهداری، آزمایشپذیری و مقیاسپذیری کد را بهبود میبخشد.
بیایید یک برنامه ساده لاراول ایجاد کنیم تا الگوی ریپازیتوری را در عمل ببینیم. برنامه ما یک api ساده دارد که می تواند محصولات موجود در پایگاه داده را مدیریت کند.
اگر از مک استفاده می کنید، می توانید دستور زیر را برای شروع کار اجرا کنید:
curl -s "https://laravel.build/laravel-products-app" | bash cd laravel-products-app ./vendor/bin/sail up -d
برای بررسی موفقیت آمیز بودن نصب، آدرس http://localhost
را در مرورگر خود ببینید.
دستور زیر را برای ایجاد یک مدل برای محصولات و مهاجرت، seeder،factory، درخواستهای فرم، قوانین و کنترلر مربوطه اجرا کنید:
sail artisan make:model Product -a
فایل های زیر ایجاد خواهند شد.
app/Models/Product.php database/factories/ProductFactory.php database/migrations/2023_07_23_113810_create_products_table.php database/seeders/ProductSeeder.php app/Http/Requests/StoreProductRequest.php app/Http/Requests/UpdateProductRequest.php app/Http/Controllers/ProductController.php
درخواست فرم و قوانین خارج از محدوده این مقاله است، اما در اصل قوانین کمک به مجوز برای یک مدل است و درخواستهای فرم برای تایید اعتبار هستند تا اطمینان حاصل شود که دادههای ما سازگار هستند.
بیایید مهاجرت را تغییر دهیم تا لاراول بداند که می خواهیم کدام فیلدها را در جدول داشته باشیم. متد up را به صورت زیر تغییر دهید:
public function up(): void { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('description'); $table->boolean('is_available')->default(false); $table->timestamps(); }); }
سپس ProductFactory را تغییر دهید تا بتوانیم برای هر محصول در پایگاه داده مقداری داده فیک ایجاد کنیم.
public function definition() { return [ 'name' => fake()->name, 'description' => fake()->paragraph, 'is_available' => fake()->boolean, ]; }
اکنون ProductSeeder
را تغییر دهید تا 100 محصول با استفاده از تعریف ProductFactory
برای ما ایجاد کند. همچنین باید DatabaseSeeder
را تغییر دهیم رسانی کنیم تا از کلاس ProductSeeder
ما استفاده کند.
public function run(): void { $this->call([ ProductSeeder::class ]); }
اکنون میتوانیم دستور زیر را برای اجرای migrations و seed دیتابیس اجرا کنیم:
sail artisan migrate --seed
IDE پایگاه داده خود را باز کنید و باید چیزی شبیه به این را در جدول محصولات خود مشاهده کنید:
ابتدا یک رابط ایجاد کنید که اینترفیس را برای ریپازیتوری شما تعریف کند. این رابط متدهایی را که ریپازیتوری باید پیاده سازی کند فهرست می کند.
?php namespace App\Repositories; interface ProductRepositoryInterface { public function getAllProducts(); public function getProductById($productId); public function deleteProduct($productId); public function createProduct(array $productData); public function updateProduct($productId, array $productData); public function getAvailableProducts(); // Add more methods as per your application needs }
بعد، یک پیاده سازی مشخص از رابط ریپازیتوری ایجاد کنید. این کلاس حاوی منطق واقعی دسترسی به داده ها خواهد بود.
<?php namespace App\Repositories; use App\Models\Product; class ProductRepository implements ProductRepositoryInterface { public function getAllProducts() { return Product::all(); } public function getProductById($productId) { return Product::findOrFail($productId); } public function deleteProduct($productId) { Product::destroy($productId); } public function createProduct(array $productData) { return Product::create($productData); } public function updateProduct($productId, array $productData) { return Product::whereId($productId)->update($productData); } public function getAvailableProducts() { return Product::where('is_available', true); } }
در لاراول، می توانید اینترفیس ریپازیتوری را به پیاده سازی آن در کانتینر سرویس متصل کنید. این به شما امکان می دهد تا ریپازیتوری را به طور خودکار در هر کجا که نیاز دارید تزریق (inject) کنید. دستور زیر را اجرا کنید:
sail artisan make:provider RepositoryServiceProvider
متد register را در کلاس تازه ایجاد شده ویرایش کنید تا ریپازیتوری خود را به کانتیتر سرویس لاراول متصل کنید:
public function register() { $this->app->bind(ProductRepositoryInterface::class, ProductRepository::class); }
آخرین مرحله ای که باید پشت سر بگذاریم این است که آرایه providers را در فایل app/config.php خود ویرایش کنیم:
'providers' => ServiceProvider::defaultProviders()->merge([ // Other providers... App\Providers\RepositoryServiceProvider::class, ])->toArray(),
ایجاد مسیریابی (routing) و کنترلر
اکنون که ریپازیتوری راه اندازی شده است، می توانید آن را به کنترلرها یا سرویس های خود تزریق کنید و از متدهای آن برای تعامل با لایه داده استفاده کنید.
<?php namespace App\Http\Controllers; use App\Http\Requests\StoreProductRequest; use App\Http\Requests\UpdateProductRequest; use App\Models\Product; use App\Repositories\ProductRepository; use App\Repositories\ProductRepositoryInterface; use Illuminate\Http\JsonResponse; use Illuminate\Http\Response; class ProductController extends Controller { public function __construct( private ProductRepositoryInterface $productRepository ) { } public function index(): JsonResponse { return response()->json([ 'data' => $this->productRepository->getAllProducts() ]); } public function store(StoreProductRequest $request): JsonResponse { return response()->json( [ 'data' => $this->productRepository->createProduct($request->validated()) ], Response::HTTP_CREATED ); } public function show(Product $product) { return response()->json([ 'data' => $this->productRepository->getProductById($product->id) ]); } public function update(UpdateProductRequest $request, Product $product) { return response()->json([ 'data' => $this->productRepository->updateProduct($product->id, $request->validated()) ]); } public function destroy(Product $product) { $this->productRepository->deleteProduct($product->id); return response()->json(null, Response::HTTP_NO_CONTENT); } }
خط زیر را به routes/api.php
اضافه کنید:
Route::apiResource('product', ProductController::class);
می توانید برنامه خود را با استفاده از Postman یا موارد مشابه تست کنید. در اینجا یک اسکرین شات وجود دارد تا بتوانید ببینید روت index چه چیزی را برمی گرداند:
برای ایجاد محصولات و به روز رسانی آنها کار بیشتری باید انجام شود. اول از همه اجازه دهید فایل StoreProductRequest.php
را ویرایش کنیم:
<?php namespace App\Http\Requests; use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Foundation\Http\FormRequest; class StoreProductRequest extends FormRequest { public function authorize(): bool { return true; } public function rules(): array { return [ 'name' => 'required|min:3|max:255', 'description' => 'required|min:3|max:255', 'is_available' => 'required|boolean' ]; } }
توجه داشته باشید که برای بازگشت true باید متد autorize را ویرایش کنید. اگر بخواهیم محصولی ایجاد کنیم و فقط از قسمت نام استفاده کنیم، یک پاسخ خطای 422 دریافت می کنیم:
همچنین باید مدل را ویرایش کنیم تا بتوانیم عملیات انتساب را انجام دهیم. این برای جلوگیری از ویرایش اشتباه فیلدها برای مثال ستون id است. فایل app/Models/Product.php
خود را ویرایش کنید و ویژگی $fillable
را اضافه کنید:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; protected $fillable = ['name', 'description', 'is_available']; }
اکنون وقتی درخواست POST ارسال می کنیم، پاسخ 201 را دریافت می کنیم:
و همچنین می توانیم ببینیم که محصول ما در پایگاه داده ایجاد شده است:
برای درخواست PUT می توانید همان تغییرات را در فایل UpdateProductRequest.php
ایجاد کنید.
دیزاین پترن ریپازیتوری ابزار قدرتمندی است که می تواند ساختار و قابلیت نگهداری برنامه های لاراول شما را به میزان قابل توجهی بهبود بخشد. با جداسازی منطق دسترسی به داده ها، به قابلیت استفاده مجدد، آزمایش پذیری و انعطاف پذیری کد دست پیدا می کنید. این مقاله یک راهنمای گام به گام برای پیاده سازی دیزاین پترن ریپازیتوری در لاراول ارائه می دهد که به شما امکان می دهد کد خود را مانند یک حرفه ای مدیریت کنید و برنامه های قوی و مقیاس پذیر بسازید. پس ادامه دهید، کد خود را تغییر دهید و از پتانسیل کامل دیزاین پترن ریپازیتوری لاراول استفاده کنید.
می توانید ریپازیتوری Github را در اینجا مشاهده کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.