احسان رضایی

یک توسعه دهنده

کتاب الگوهای طراحی به بیان ساده(design patterns/دیزاین پترن)

در مهندسی نرم افزار، design patterns(الگوهای طراحی) راه حل‌های قابل استفاده برای مشکلاتی هستند که معمولاً در طراحی نرم‌افزار اتفاق می افتند.

طرح های از پیش ساخته شده‌ای که می‌توانید برای حل مشکلات آن‌ها را سفارشی کنید. شما نمی‌توانید یک الگو را با جستجو در stackoverflow پیدا و در برنامه خود کپی کنید. الگو ها یک قطعه کد خاص نیستند، مفاهیم کلی برای حل مشکلات خاص هستند. شما باید با درک این مفاهیم آن‌ها را در برنامه خود پیاده‌سازی کنید.



الگوی طراحی مخزن در لاراول(Repository Design Pattern)

در laravel , / تاریخ ارسال 1399/11/02 - 03:02 / 1 نظر / 399 بازدید / آخرین ویرایش 1400/09/08 - 11:13

حتما چنین کدی رو قبلا دیدین:

    public function index() : JsonResponse
    {
        $cars = Car::with('facilities', 'type', 'color', 'rentalDetail')->all();
        return response()->json($cars, 200);
    }

هوم... . مورد بدی توش دیده نمیشه. یک سرویس ساده که لیست خودرو ها رو میده. اما منطق/logic توی کنترلر نوشته شده. هر چند به عقیده من آوردن منطق در کنترلر برای app های کوچک مشکلی به وجود نمیاره اما با رشد نرم افزار بیشتر و بیشتر نیاز به یک ساختار منسجم و متمرکز رو حس میکنید.

به عنوان یک روش جایگزین و بهتر میشه از الگوی طراحی مخزن یا بهتر هست بگیم Repository Design Pattern استفاده کرد. مثل همیشه ساده بگم، در این روش مسئولیت ارتباط و استخراج داده ها رو از روی دوش مدل برمیداریم و اون رو در کلاس های Repository پیاده میکنیم، داخل کنترلر هم فقط متد هاشون رو صدا میزنیم.

    public function index() : JsonResponse
    {
        $cars = $this->carRepository->get();
        return response()->json($cars, 200);
    }

این روش مزیت های زیادی داره از جمله:

- ایجاد ساختاری منسجم و متمرکز
- حذف کد های تکراری
- توسعه و نگهداری آسانتر
- کاهش خطا و خطایابی سریعتر
- از بین بردن وابستگی های بین مدل و کنترلر
- کد تمیز و واضحتر

خب به نظرم توضیحات تا همین اندازه کافی هست و بهتره بریم سراغ یک نمونه ساده از پیاده سازی این روش تا مزایایی که بهمون میده رو بیشتر درک کنید.

برای مخازن چنین ساختاری رو در نظر میگیریم.

 

-- app
---- Repositories
------ CarRepository.php
------ BaseRepository.php
------ RepositoryInterface.php

 

با استفاده از RepositoryInterface الگو و ساختار پیشفرض کارمون تعریف میشه. متد هایی که تمام مخازن باید یک نمونه پیاده سازی اون رو داشته باشن. 

interface RepositoryInterface
{
    public function get();
    
    public function find($id);
    
    public function create($data);

    public function update($data, $id);

    public function delete($id);
}


در BaseRepository متدهای مشترک بین تمام مخازن رو پیاده میکنیم. مخازن از این کلاس extend میشن. این کلاس به حذف کدهای تکراریمون کمک میکنه.

class BaseRepository implements RepositoryInterface 
{     

     protected $model;       

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

    public function find($id)
    {
        return $this->model->find($id);
    }

    public function create($data)
    {
        return $this->model->create($data);
    }

    public function update($data)
    {
        return $this->model->update($data);
    }

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

 

و مخزن خودرو. همون مثالی که زدیم.

class CarRepository extends BaseRepository
{
    public function __construct(Car $model)
    {
        parent::__construct($model);
    }

    public function get()
    {
        $cars = $this->model->with('facilities', 'type', 'color', 'rentalDetail')
            ->orderByDesc('id');

        return $cars;
    }
}


استفاده.

class CarController extends Controller
{

    private $carRepository;

    public function __construct(User $model)
    {
        $this->carRepository =  new CarRepository($model);
    }

    public function index(): JsonResponse
    {
        $cars = $this->carRepository->get();
        return response()->json($cars, 200);
    }

    public function create(CarRequest $request) : JsonResponse
    {
        $cars = $this->carRepository->create($request->all());
        return response()->json(null, 204);
    }
    
    .
    .
    .
}

 

نکات آخر.
- این یک نمونه ساده از پیاده سازی Laravel Repository Pattern به منظور درک سریع و بهتر موضوع بود. طبیعتا روش های پیاده سازی متفاوتی رو با گشتن در اینترنت خواهید دید.
- همونطور که توضیح دادم مخازن کار با دیتا رو انجام میدن و دیگه از مدل استفاده نمیکنیم.
- توی مثال ها چند متد رایج رو آوردم. هر نوع درخواست(کوئری) باید در مخازن تعریف و داخل کنترلر صدا زده بشه.
- در استفاده از این روش اجباری نیست.
- در مدل پیاده سازی این روش قانون سختگیرانه ای وجود نداره.

موفق باشید.

ارسال نظر

علی در تاریخ 1399/12/28 - 10:47 نوشته
خیلی ساده و روان بود. خدا قوت