تقریبا هر توسعه دهنده ی وب استایل خاص خود در کدنویسی را دارد اما اگر از فریمورکی مثل لاراول استفاده میکنید که همه چیز سرجای خودش قرار دارد تقریبا استایل کدنویسی همه مشابه هم میشود ولی به شرط اینکه آنرا به درستی یاد بگیریم و درست تمرین کرده باشیم.
ما بعنوان یک توسعه دهنده ی وب باید مطمئن شویم که کدهای ما از نظر نگهداری ، بروزرسانی و تست در اینده مشکلی نخواهد داشت مخصوصا اگر کار تیمی است یا قرار است بعد از ما افراد دیگری کد را ببینند.
چه چیزی باعث میشود که بعنوان توسعه دهنده ی وب کدهای ما بد به نظر برسد ؟ از آنجایی که لاراول یک فریمورک برای زبان برنامه نویسی PHP است و پی اچ پی هم کاملا شی گرا است بهتر است از اصول و قواعد شی گرایی یا OPP به درستی استفاده کنیم
از انجایی که فریمورک لاراول خیلی محبوب است جامعه ی بزرگی هم دارد و ممکن است بعضی مواقع این جامعه ی بزرگ قراردادی در کدنویسی تصویب کند که بعنوان اصول کدنویسی با لاراول نیز شناخته میشود.
در نتیجه رعایت این اصول باعث میشود دیگر برنامه نویسان لاراول نیز بتوانند کدهای ما را سریعتر و بهتر درک کنند.
ما در این مقاله ۷ تمرین عالی برای درک اصول برنامه نویسی با لاراول ، استاندارد های لاراول و استانداردهای قراردادی جامعه ی لاراول میپردازیم.
اگر یک query پیچیده یا SQL خام داریم که درون کنترلر نوشتیم این کار اشتباه است، باید این کوئری را به مدل ها یا repository های لاراول منتقل کنیم. به مثال زیر دقت کنید تا متوجه شوید.
کدی که از نظر اصولی بد است :
<?php public function index() { $partners = Partner::where('email_verified_at', '!=', null) ->with(['products' => function ($q) { $q->whereDate('created_at', now()); }]) ->get(); return view('index', ['partners' => $partners]); }
کدی که از نظر اصولی خوب است :
<?php public function index() { return view('index', ['partners' => $this->partner->newProducts()]); } class Partner extends Model { public function newProducts() { return $this->where('email_verified_at', '!=', null) ->with(['products' => function ($q) { $q->whereDate('created_at', now()); }]) ->get(); } }
همانطور که در نکته ی شماره ی ۱ دیدید ما سعی داریم کنترلر ها را ساده تر و کم حجم تر نگهداری کنیم پس باید تمامی business logic را به کلاس های Service جداگانه منتقل کنیم.
پس باید هر کنترلر داری یک مسئولیت باشد و ما میتوانید کلاس های Service جدا ایجاد کنیم و آنها را درون کنترلرها فقط فراخوانی بکنیم. به مثال زیر دقت کنید تا متوجه موضوع شوید.
کدنویسی غیراستاندارد با لاراول :
<?php public function store(Request $request) { $user = User::create(); $user->update(['last_login' => now()]); dispatch(new UserCreated($user)); // ... }
کدنویسی استاندارد با لاراول :
<?php public function store(Request $request) { $this->userService->create($request); .... } class UserService { public function create($request) { // ... } }
استفاده از Eloquent بسیار راحت تر و ایمن تر از SQL نویسی خالی است ، از حملات SQL Injection جلوگیری میشود و نگهداری آن راحت تر است.
نمونه کدنویسی غیراستاندارد :
<?php SELECT * FROM `articles` WHERE EXISTS (SELECT * FROM `users` WHERE `articles`.`user_id` = `users`.`id` AND EXISTS (SELECT * FROM `profiles` WHERE `profiles`.`user_id` = `users`.`id`) AND `users`.`deleted_at` IS NULL) AND `verified` = '1' AND `active` = '1' ORDER BY `created_at` DESC
نمونه کدنویسی استاندارد :
<?php Article::has('user.profile')->verified()->latest()->get();
در لاراول ما باید سعی کنیم طوری کد نویسی کنیم که بتوانیم دوباره از کامپوننت ها یا logic های مختلف استفاده کنیم یا اصطلاحا نباید don't repeat yourself بشیم که یعنی تکرار کارهایی که قبلا یکبار انجام دادیم.
در فرانت اند وب سایت با لاراول میتوانیم در قسمت Blade کامپوننت هایی بسازیم که قابلیت استفاده مجدد داشته باشند یا در بک اند قسمت logic میتوانیم بخش هایی ایجاد کنیم که از آنها مجدد استفاده کنیم مثل service class ، eloquent scope یا حتی ساختن یک پکیج شخصی برای کار خاصی ...
یک مثال خوب :
<!DOCTYPE html> <html> <head> <title>DRY</title> </head> <body> <h1>Custom Calendar</h1> <x-custom-calendar> </body> </html>
حتی اگر در فریمورک لاراول به شما اجازه داده شده که کوئری های خود را در قالب سایت و در بخش view انجام بدهید این کار از نظر استاندارد درست نیست و نباید انجام بدهید.
نمونه کدنویسی بد بخاطر ایجاد هزاران مشکل :
@foreach (User::all() as $user) {{ $user->email }} @endforeach
نمونه کدنویسی استاندارد و خوب:
$users = User::all(); // Server Query @foreach ($users as $user) {{ $user->email }} @endforeach
اگر ما کوئری ها یا logic های پیچیده و طولانی داریم بهتر است transaction مربوط به DB را حتما درنظر داشته باشیم.
با استفاده از این فیچر در صورت نیاز می توانیم به راحتی DB را برگردانیم تا مطمئن شویم که داده های ما در DB ذخیره نشده اند. در این صورت به داده های خود اطمینان بیشتری داریم.
به کدهای زیر دقت کنید :
<?php public function store(Request $request) { DB::beginTransaction(); $user = User::create(); $response = app('service')->create($user); if (!$response) { DB::rollback(); return; } // ... DB::commit(); }
ما نباید رشته های متنی را بصورت hardcode یا دستی درون کنترلها یا هرکجای کدهای لاراولی بنویسیم.ما میتوانیم برای این کار از translation استفاده کنیم تا نگهداری و ویرایش رشته های متنی در آینده نیز آسانتر شود. ما میتوانیم از translation در کلاس های خود در بخش کنترلرها ، مدل ها و ... حتی درون config نیز بهره ببریم.
trans('user.created'); // 'User Successfully Created' $types = Product::TYPES; // Const in a Class/Model
سخن پایانی
لاراول یک ابزار عالی برای توسعه ی وب است و تا حدودی سعی دارد برنامه نویس را درون چهارچوب و استاندارد خوب نگهداری کند. هرچند شما میتوانید به هر شکل و شیوه ای در لاراول برنامه نویسی کنید ولی بهتر است با تمرین های مختلفی اصول و استانداردهای لاراول را رعایت کنید تا هم کدهای شما در آینده قابل درک باشد و هم اینکه پروژه ی خود را به راحتی بتوانید بروزرسانی کنید.