دیزاین پترن 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 مدلم تعریف کردم - امیدوارم کم کم بریم سمت حرفه ای نوشتن .ارادت