همانطور که میدانید کنترلرها در لاراول عناصر اصلی از ساختار ( MVC ( model view controller هستند. کنترلرها میتوانند به صورت غیر قابل کنترلی در اپلیکیشن شما رشد کرده و بزرگ و بزرگتر شوند، به عنوان یک توسعه دهنده باید همیشه به این فکر کنیم که چگونه میتوانیم مفهوم ذهنی مورد نظر خود را پیاده سازی کنیم به طوری که کد خود را کوتاهتر، مرتب تر و با تکرار کمتر بنویسیم.
پیاده سازی یک مفهوم در یک کنترلر کاملاً مطلوب است به خصوص هنگامی که شما میدانید فقط یک نقطه پایان دارید. امروزه در توسعه اپلیکیشنهای مدرن بسیار متداول است که شما باید ضمن به اشتراک گذاشتن توابع یکسان با چندین نقطه پایانی در توسعه خود سرو کار داشته باشید.
بنابراین شما باید چندین روش را برای پیاده سازی و تست کنید تا پاسخ درست را برگردانید، همچنین من گاهی اوقات مشاهده کردهام، کنترلرها با لیست عظیمی از کلاسهای وابسته باعث ایجاد یک کنترلر خیلی بزرگ شده و مدیریت آن را دشوار میکند. لاراول برای حل این مشکل service container را پیشنهاد داده است که استفاده از آن باعث رفع مشکل است کنترلرهای بزرگ می شود، اما با این وجود هنوز مشکل ما حل نشده و کنترلر ما کثیف و شلخه است.
اخیراً من در یکی از پروژههای خود با این مسئله روبرو شدم که حتی با وجود استفاده حداقل از کلاسها در یک کنترلر که روی یک مدل کار میکرد، هنوز هم این کنترلربسیار بزرگ بود. به عنوان مثال در یکی از پروژهها من یک مدل Movie و یک کنترلر MovieController در کنترلرهای خود داشتم. در این پروژه من متدهای زیادی مانند storeMovie، searchMovie، storeActorsForMovie، loadMovieImages ،uploadMovieImages و خیلی چیزهای دیگر داشتم. من میتوانستم آنها را به کنترلرهای مختلفی تقسیم کنم، اما چطور؟ باید به این فکر میکردم که کدام قسمت را باید جدا میکردم و آن را باید به کجا انتقال میدادم؟
راه حل
یکی از راه حلهایی که من پیدا کردم استفاده از کلاس های invokable بود. استفاده از magicمتد __invoke() به همراه یک کلاس تک اکشن.
من برای ساخت یک تک اکشن فقط یک متد __constructor() و متد __invoke() را نوشتهام.
__invoke() یک تابع magic در php است و هنگامی که ما میخواهیم یک نمونه از کلاس ایجاد کنیم یا به این کلاس فراخوانی کنیم __invoke() به صورت خودکاربارگیری میشود. با استفاده از این روش شما، ما از رویکرد ( SRP ( Single Responsibility Principle
SRP بدین معنا که هر کلاس باید یک دلیل برای تغییر داشته باشد.
استفاده از این روش باعث میشود برنامه شما قویتر و آزمایشتر باشد. شما میتوانید پاسخ مورد نیاز خود را برگردانید.
برای ایجاد یک کنترلر تک اکشن در لاراول، شما باید یک نام برای کنترلر خود انتخاب کنید که نشان دهندهی اکشن مورد نظر شما باشد، همچنین در این روش شما زمان کمتری را صرف پیدا کردن متد مورد نظر خود در یک کنترلر بزرگ میکنید.بنابراین برای MovieController ، میتوانیم آن را به SearchMovieController, LoadMovieImagesController UploadMovieImagesController و... تقسیم کنیم.
شما میتوانید مشاهده کنید که این کنترلرها در حال حاضر با استفاده از این نامها توضیحیتر شدهاند وهمچنین میدانید که آنها فقط یک اکشن با استفاده از متد __invoke() اجرا می کنند.
در ادامه روتهای من از شکل زیر:
Route::post('searchMovie', 'MovieController@searchMovie');
Route::get('loadMoviesImages', 'MovieController@loadMovieImages');
به این شکل تغییر میکند:
Route::post('searchMovie', 'SearchMovieController');
Route::get('loadMoviesImages', 'LoadMovieImagesController');
کنترلر به شکل زیر خواهد شد:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchMovieController extends Controller
{
public function __invoke()
{
// do movie search here
}
}
به طور مشابه من میتوانم همهی کنترلرهای خود را فقط برای یک اکشن خاص ایجاد کنم.
اشکالات
مثال بالا، نمونهی خیلی خوبی برای کلاس تک اکشن است که کدنویسی را تمیز و مرتب نگه می دارد اما محدودیتهای برای این روش وجود دارد.
اگر ما از این روش استفاده کنیم، نمیتوانیم از روت resouceها مانند Route::resource(); استفاد کنیم. شما برای هر روت resource خود باید یک کنترلر متناظر تعریف کنید.
در این مقاله تلاش شد به بررسی کنترلرهای تک اکشن پرداخته شود. در صورت هرگونه سوال میتوانید آن را در قسمت نظرات بیان کنید.
دیدگاه و پرسش
در حال دریافت نظرات از سرور، لطفا منتظر بمانید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید