لاراول در لولهکشی Decorator
داشتم اینترنت رو زیر و رو میکردم نه برای پیدا کردن راهی، برای یادگرفتن چیز های جدید.
تصمیم گرفتم برم چندتا دیزاین پترن دیگه یادبگیرم
> دیزاین پترنها به من بیشتر از برنامهنویسی سبک فکر کردن رو یاد میدند!
از دیزاین پترنهای ساده شروع کردم، یک پترن جالب پیدا کردم به اسم **Decorator** کارش این بود که یکسری تغییرات رو به صورت سلسله مراتب روی ورودی انجام بده و خروجی نهایی رو برگردونه.
کارش خیلی باحاله، مثلا شما یه متن دارید قراره کار های زیر رو به ترتیب روش اعمال کنید.
۱. حذف کلمات رکیک
۲. حذف نماد های اضافه
۳. حذف فاصله های اضافه
۴. اضافه کردن نیمفاصله
میشه همه این قانین رو یکجا نوشت و توسعهاش روز به روز سخت تر و سختتر میشه یا بیایم از این دیزاین پترن استفاده کنیم.

> دیاگرام بالا فقط برای درک بهتر هست، ما با همون متن پیش میریم که ساده تر باشه
برای این دیزاین پترن به یک **Interface** نیاز داریم به این صورت
“`php
😅 اسم گذاری یکم سخته !!
خب _class_ بالا اصل داستان هست و دیتا از اونجا وارد میشه حالا هر شیوهای که دوست دارید.
تا اینجا همون داستان قبلی هست، فرض کنید که **MainData** جمله رو گرفته و کلمات رکیک رو حذف کرده.
فردا دوباره میرید پای کار و میبینید که باید علامتهای اضافه هم پاک کنید.
یک _class_ دیگه اضافه میکنم، از این جا داستان داره یکم عوض میشه!
“`php
component = $component;
}
public function operation(): string
{
return $this->component->operation();
}
}
“`
_class_ ما باید دوباره از _interface_ ارث بری کنه و یک متد سازنده یا **Constructor** داشته باشه که ورودیش یک کلاسی باشه که از همون _interface_ ارث بری میکنه.
حالا وقت اون رسیده که قوانین رو بسازیم، هر قانون یک **Class**.
> قوانین باید از کلاس **بالا** ارثبری کنند.
“`php
operation();
“`
خب کد بالا متن خام رو برمیگردونه مثل روز اول، اگر میخواید که قوانین اعمال بشه باید کد زیر رو استفاده کنید.
“`php
operation();
“`
به همین صورت میشه میلیون ها قانون دیگه اضافه کرد بدون این که هر کدوم به هم وابستگی خاصی داشته باشند.
توی **لاراول** از این پترن هم استفاده شده، اگر بخواید توی لاراول همچین چیزی داشته باشد میتونید از کلاس _\Illuminate\Pipeline\Pipeline::class_ استفاده کنید که کار رو خیلی ساده کرده.
متدهای این کلاس شامل
– **Send** ورودی ما به Pipe هست برای پرداشز
– **through** ورودی ما از طریق این متد که یک آرایه ای از کلاس هارو به عنوان ورودی میگیره پردازش میشه.
– **via** این متد هم یک اسم از ما میگیره به عنوان اسم متدی که توی کلاس های بالا باید صدا زده بشه که به صورت پیشفرض روی _handle_ تنظیم شده.
– **then** بعد از این که پردازش ها تموم شد این متد صدا زده میشه که یک فانکشن به عنوان ورودی میخواد و نتیجه رو به اون فانکشن پاس میده.
– **thenReturn** اگر توی کلاس اصلی بهش نگاه متوجه میشید که دقیقا متد بالا رو صدا زده و نتیجه رو توی ورودیش برگردونده.
به ۲ حالت میشه ازش استفاده کرد.
“`php
app(\Illuminate\Pipeline\Pipeline::class)
->send(\”salam\”)
->through([
Class۱::class,
Class۲::class,
.
.
.
])->thenReturn();
“`
یا
“`php
$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe->send(\”salam\”)
->through([
Class۱::class,
Class۲::class,
.
.
.
])->thenReturn();
“`
توی نگاه اول میگید خب اولی بهتره و قطعا دلیل اصلیتون اینه که به پایپ لاراول نمیشه دیتایی ارسال کرد، باید بگم که اشتباه میکنید برای ارسال پارامتر اضافه میشه توی متد سازنده کلاس ها ورودی رو بگیرید و بدید به پایپ به این صورت
“`php
$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe->send(\”salam\”)
->through([
new Class۱($param),
new Class۲($param,$arg)
])->thenReturn();
“`
این پایپ خیلی دستمون رو باز گذاشته حتی میتونید بهش فانکشن هم پاس بدید و نیاز به کلاس نداشته باشید.
“`php
$pipe=null \Illuminate\Pipeline\Pipeline();
$pipe->send(\”salam\”)
->through([
function($content,\Closure $next){
return $neext($content);
},
function($content,\Closure $next){
return $neext($content);
}
])->thenReturn();
“`
> داشت یادم میرفت اگر خواستید کلاسی به این پایپ ارسال کنید حتما متد **handle** رو ایجاد کنید یا با متد _via_ متد خودتون رو معرفی کنید.
این متد ۲تا ورودی داره یکی رو از شما میگیره که همون مقداری هست که به _send_ دادید و ورودی دوم هم یک فانکشن هست که وظیفه انتقال اطلاعات رو برعده داره.
چون مینویسم هستم.
