دیزاین پترن Repository در لاراول

ویرگول همش اول شروع نوشتن میگه " هرچی دوست داری بنویس ".

یک سری هم واقعا همینکارو میکنن . جالبه که هرچی به ذهنشون میرسه میگن .

منم امروز این مورد به ذهنم رسید .

تصمیم گرفتم که روش های درست رو برای نوشتن کدهای تمیز انتخاب کنم .

چند وقته که توی گروه های اسمشو نبر ( تل گ ر ام :-| ) میبینم که ایرادا بیشتر به خاطر اینه که درک درستی از شی گرا و اصول SOLID وجود نداره .

منم همینطورم . شاید خیلی کم پیش بیاد که توی پروژه ، اصول رو رعایت کنم . اینجا هم نیستم که چیزی یاد کسی بدم و وقتی ادعای آموزش میشه ، توقع چیز دیگست ( خیلی دل نترس میخواد که به یکی بگی دارم بهت چیزی یاد میدم . مگر اینکه واقعا استاااااااااااااد باشی )

بگذریم .

من برای پروژه هام به تازگی از design pattern به اسم Repository استفاده میکنم که فلوچارتش میشه تصویری که گذاشتم .

در کل کار این دیزاین پترن اینه که شما از یک Database یک سری اطلاعات رو دریافت کنید و طبق یک mapper و الگو ، پاس بدید به کنترلر و بعد از اون مراحل معماری خودتون رو برید جلو ( که توی لاراول MVC هست و پس مسلما بعدش میریم سمت View ) .

ریپوزیتوری ، یک سری Data Object یا به زبون خودمونی یک سری شئ ایجاد میکنه که داخلشون داده ها قرار دارن و با استفاده از Interface که براش طراحی میکنیم میتونه عملیاتی رو روی این داده ها انجام بده .

بدون شک برای دریافت اطلاعات از Eloquent استفاده میکنیم .

باحاله . نه؟

حالا بزن بریم .

اول از همه یک پوشه درست کنیم به اسم Repositories داخل پوشه app لاراول .

داخل این پوشه یک فایل Repository درست کنید و کد زیر رو داخلش قرار بدید .

<?php
/**
 * Created by PhpStorm.
 * User: nima
 * Date: 1/15/19
 * Time: 12:42 PM
 */

namespace App\Repositories;

use Illuminate\Database\Eloquent\Model;

class Repository implements RepositoryInterface
{
    // model property on class instances
    protected $model;

    // Constructor to bind model to repo
    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    // Get all instances of model
    public function all()
    {
        return $this->model->all();
    }

    // create a new record in the database
    public function create(array $data)
    {
        return $this->model->create($data);
    }

    // update record in the database
    public function update(array $data, $id)
    {
        $record = $this->find($id);
        return $record->update($data);
    }

    // remove record from the database
    public function delete($id)
    {
        return $this->model->destroy($id);
    }

    // show the record with the given id
    public function show($id)
    {
        return $this->model->findOrFail($id);
    }

    // Get the associated model
    public function getModel()
    {
        return $this->model;
    }

    // Set the associated model
    public function setModel($model)
    {
        $this->model = $model;
        return $this;
    }

    // Eager load database relationships
    public function with($relations)
    {
        return $this->model->with($relations);
    }
}

خوب . داخل این فایل رو اگر دقت کنید میبینید که من چند متود دارم که این متود ها همه دارن از eloquent استفاده میکنن و یک سری کوئری میزنن . تنها چیزی که مهم است اینه که الگوی ما از یک interface پیروی میکنه به اسم RepositoryInterface.

خوب این فایل هم بسازیم کنارش .

<?php

namespace App\Repositories;

interface RepositoryInterface
{
    public function all();

    public function create(array $data);

    public function update(array $data, $id);

    public function delete($id);

    public function show($id);
}

تا اینجا که چیزی نداشت .

حالا بریم داخل کنترلر و کوئری بزنیم .

<?php

namespace App\Http\Controllers;

use App\movie;
use App\Repositories\Repository;
use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    protected $movie;
    public function __construct(movie $movie)
    {
        $this->movie = new Repository($movie);
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        $movies=$this->movie->all();
        return view('welcome',["movies"=>$movies]);
    }
}

خوب اومدم داخل این کنترلر Repository رو use کردم و برای مدل movie یک instance از این ریپوزیتوری ایجاد کردم ( ببخشید اصطلاح ها خارجی شده . من سواد ندارم بدونم فارسیشون دقیقا چی میشه .)

داخل index هم گفتم متود all رو صدا بزن از property که ساخته بودیم و به مدل movie وصله .

چرا حالا ما اینکارارو میکنیم؟

دلیل اینه که ما میخوایم یک سری تابع بنویسیم که شاید داخل پروژه خیلییییی کاربرد داشته باشن . مثل توابع join که برای اکثر دوستان دیگه خسته کننده شده . شما میتونید یک بار بنویسید و چند جا استفاده کنین . به همین راحتی و سادگی .

باقی توابع هم میشه به سادگی استفاده کرد . برای مثال تابع create :

public function store(Request $request)
   {
       return $this->movie->create($request->only($this->model->getModel()->fillable));
   }

داخل این متود ما میتونیم تمام مقادیر که میخوایم رو پاس بدیم تا ذخیره سازی انجام بشه .

شاید چیزی که نوشتم کمی نا مفهومه . خیلی ساده ست در واقع .

من نوشتم که ذخیره کن ، هر چیزی که توی request وجود داره - امااااااااا فقط اونایی که داخل fillable مدلم تعریف کردم -

امیدوارم کم کم بریم سمت حرفه ای نوشتن .

ارادت