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

الگوی آداپتور (الگوی وفق دهنده) - Adapter pattern با مثال PHP

Adapter pattern
Adapter pattern

الگوی آداپتور یک الگوی که یاد گیریش ساده است چون که همه ما در دنیای واقعی ازش استفاده میکنیم مثل همین تبدیل های سه شاخه به دوشاخه برق، پس درکش برامون ساده اس.

تبدیل سه شاخه به دوشاخه برق
تبدیل سه شاخه به دوشاخه برق

اول ببینیم آداپتور(مبدل) چه کاری رو برامون انجام میده؟!! من یه مانیتور دارم که به برق نیاز داره که روشنش کنم اما دو شاخه و پریز برق از یک استاندار یا به زبان کد بخوام بگم یک اینترفیس ندارن خب من نیاز به یک وسیله رابط دارم که بتونم دوشاخه رو به پریز وصل کنم خب آداپتور یا به زبان عمیانه تبدیل یا مبدل استفاده میکنم.(آداپتور شارژ لپ تاپ هم از همین موضوع میاد چون برق شهری 220 ولت رو به برق قابل استفاده برای شارژ لپ تاپ یعنی حدود 9 ولت تبدیل میکنه)

فکر کنم حالا میشه حدس زد این دیزاین پترن چی کار میکنه، بریم با یه مثال یاد بگیریم چطوری پیاده سازیش کنیم.

یک مثال ابتدایی در مورد کتاب بزنیم، بیاین تصور کنیم که ما کتاب کاغذی داریم و هر کسی که میاد کتاب بخونه ما کتاب رو واسش باز میکنیم و براش کتاب رو ورق میزنم.

بیاید از درست کردن یک interface برای کلاس کتاب شروع کنیم و سعی کنیم از قوانین SOLID استفاده کنیم. اگه نمی دانید اینترفیس چیه پیشنهاد میکنم یکم در مورد اینترفیس، کلاس و ابسترکت کلاس(class, abstract class, interface) بخونید چیز جالبی هستش و اگه بخوام خیلی خلاصه بگم: یک اینترفیس فقط به شما اجازه می دهد که تا عملکرد(functionality) را تعریف کنید و نه این که آن را اجرا کنید. در حالی که یک کلاس می تواند یک کلاس انتزاعی (abstract class) را گسترش(extend) دهد و می تواند از چندین اینترفیس استفاده کند.



https://gist.github.com/vahid-almasi/4d7ad830ce06aa26db24b8aeb2a8d4a1

خب یه interface BookInterface ساختیم و بهش دو تا متد open و turnPage رو دادیم.

توی فایل بعدی یک کلاس Book ساخیتم و از اینترفیسکه داریم implements اش کردیم (معنیش این میشه که این کلاس باید دو تا متدی که توی اینترفیس بالا تعریف اش کریدم رو باید داشته باشه) و دو تا متد رو هم واسش ساختیم، داخل متد ها فقط برای این که مشخص شه، کاری که میکنند رو var_dump کردیم.

فایل سومی هم همون index.php ما هستش که کلاس person (شخص) رو توش نوشتیم، که یک متد read (خواندن) داره، که شئ ای که کتاب باشه رو بهش میدیم و اون برامون متد های open و turnPage رو اجرا میکنه, برای جلوگیری از این مشکل که شئ ای به جز کتاب بهش داده نشه از تله type-hinting استفاده کردیم (یه جور مثل ولیدیشن عمل میکنه، که مقدار ورودی حتما شئ (obj) باشه و از BookInterface ایمپلمنت شده باشه که حتما اون دو تا متد open و turnPage رو داشته باشه)

تا اینجا همه چی رو به راهه و سیستم داره درست کار میکنه، اما سیستم نیاز یه گسترش پیدا میکنه و ما باید کتاب خوان های الکترونیکی رو هم وارد همین سیستم کنیم. مثل کتاب جلوی افراد بذاریمش، روشنش کنیم و کتاب داخلش رو ورق بزنیم، اما یه مشکلی هست که این دستگاه ها به جای متدهای open و turnPage، متدهای turnOn و pressNextButton دارند.

https://gist.github.com/vahid-almasi/f37d96363c4689bc25ba10572ffded8d
https://gist.github.com/vahid-almasi/ef7da848de6328ed1f0914a0102704a2

فک میکنم که واضحه چی شد دقیقا کاری که برای کتاب انجام دادیم برای این هم تکرار شده، فقط اینو یادتون باشه که ما داریم توی یه شرایط فرضی این مطلب رو میگیم حتی میتونید فرض کنید که این کلاس داخل یک پکیج به شما داده شده و حق بازنویسی این پکیج رو ندارید اما باید از اون استفاده کنید. حالا دقیقا اون جاییه که ما نیاز به یک آداپتور(مبدل) داریم.

برای این کار باید کلاسی بسازیم که از ورودیش eReaderInterface باشه و خروجیش BookInterface پس میشه چیزی شبیه این

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

برای این که ورودی تابع قوانین این "ReaderInterface" اینترفیس باشه همین اینترفیس رو گذاشتیم واسه type-hinting (قبل آرگومان ورودی متد کانستراکتور) و برای این که کلاس خروجیش تابع قوانین این "BookInterface" اینترفیس باشه کلاس رو از همین اینترفیس ایمپلمنتس میکنیم، حالا متد turnOn رو داخل Open و pressNextButton رو داخل turnPage بر میگردونیم.

و از آداپتوری که ساختیم اینجوری استفاده میکنیم

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

امیدوارم قابل فهم بوده باشه، اگه نظری انتقادی برای بهتر شدن مطلب هست لطفا از یه طریقی به من نظرتون رو برسونید خوشحال میشم.

و در آخر لینک کامل پروژه روی گیت هاب و منبع که همون جفری وی عزیز هست و من فقط برداشت های خودم رو در قالب این مطلب نوشتم.

https://github.com/laracasts/Getting-Jiggy-With-Adapters
https://laracasts.com/series/design-patterns-in-php/episodes/2



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