vahid almasi
vahid almasi
خواندن ۲ دقیقه·۵ سال پیش

الگوریتم آذینگر - Decorator pattern با زبان PHP

الگوریتم آذینگر - Decorator pattern با زبان برنامه نویسی PHP
الگوریتم آذینگر - Decorator pattern با زبان برنامه نویسی PHP


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

همونجوری که میتونید تصور کنید این تعمیرگاه میتونه خدمات مختلفی داشته باشه اما اولین و پایه ای ترین سرویسش چک(معاینه) کردن ماشین هستش

https://gist.github.com/vahid-almasi/6f31e2470c5374e5b7b49a1f0811fece

وقتی کد رو اجرا کنید 19 رو توی خروجی میبینید که درسته، حالا فک کنید که خدمات دیگه ای مثل تعویض روغن(oil change) یا جابه جایی لاستیک (tire rotation ) رو هم به سرویس ها اضافه کنیم.


https://gist.github.com/vahid-almasi/c8ae8665cf2cd13ebedcb23db8b8db3b

خروجی عدد درستی هست اما اگر دقت کنید با کوچیک ترین تغییر همه چی به هم میریزه مثلا اگر قیمت معاینه ماشین تغییر کنه! چون ما همه قیمت ها رو هاردکد کردیم باید همه قیمت ها رو پیدا کنیم و تغییرشون بدیم، حالا فک کنید که فقط یک عدد ساده نباشه و مبلغ با یه فرمول و چندین تا شرط محاسبه بشه!! یا اگه کسی فقط نیاز به تعویض روغن داشته باشه تکلیف چی میشه؟!!

خب اگر بخوایم بهتر بنویسیمش میتونیم این کار رو انجام بدیم:

https://gist.github.com/vahid-almasi/5b9ec68002817ad6a3f038444612392d

خب اول از همه یک interface درست کردیم که همه کلاس ها رو از اون implements کنیم که همه مجبور باشند که یک public function getCost داشته باشن و حتی آرگومان ورودی construct__ رو هم باهاش ولیدیت (راستی آزمایی) کردیم، بعد شئ(object) ورودی رو به یک مقدار protected دادیم و از تابع getCost این شئ، داخل این کلاس استفاده کردیم و مقدار این سرویس رو با سرویس ها قبلی جمع زدیم.

چیز باحالی که این الگوریتم داره این هستش که میتونیم حالت های مختلفی رو داشته باشیم و به اندازه ای که نیاز داریم داینامیک(پویا) باشه، میشه تا دلتون میخواد سرویس جدید به تعمیرگاه اضافه کرد و مبلغ هر سرویس رو جدا یا با هم محاصبه کرد

بیاید یک کم گسترشش بدیم و توضیحات(Description) بهش اضافه کنیم

https://gist.github.com/vahid-almasi/fc26e8dc8c3002abcf9c7a8ffbfa4e25

خب راستش برا اولین بار که این الگوی آذینگر یا Decorator pattern رو دیدم یکم گیج شدم و فک کردم خب این چه کاریه من میتونم اینو اینجوری انجام بدم

https://gist.github.com/vahid-almasi/85b2779734f78bd461e1073a9565b146

ولی این دو تا چه فرقی با هم دارن؟!! چرا وقتی می تونم انقدر ساده موضوع رو حلش کنم انقدر کلاس درست کنم؟!!

مهم ترین موضوع اینه که توی حل مسئله بالا یکی از قوانین SOLID رو یعنی اصل باز/بسته بودن کلاس ها یا همون Open-closed principle رو رعایت نکردیم، اگه شما هم مثل من هستید و یادتون میره این قانون چیه، ساده ترین تعریف اش میشه: " کلاس ها باید به سادگی و بدون نیاز به تغییر قابل گسترش ( extendable ) باشند" و اگه کلا نمی دونید چی هست پیشنهاد میکنم قوانین SOLID رو بخونید. اون وقت میفهمیم که این الگو به ما کمک میکنه که اصول شئ گرایی رو رعایت کنیم و در نهایت کد های تمیز تر و توسعه پذیری بیشتری داشته باشیم.

در اخر با تشکر از Jeffrey Way عزیز منبع :

https://laracasts.com/series/design-patterns-in-php




phpالگوریتمدکوراتورآذینگربرنامه نویسی
PHP/Back-End Developer and Freelancer -- می نویسم که بیشتر یاد بگیرم و طولانی تر یادم بمونه :)
شاید از این پست‌ها خوشتان بیاید