Ali Shobeyri
Ali Shobeyri
خواندن ۵ دقیقه·۵ سال پیش

الگویِ طراحی Adapter (جاوا و کاتلین)

کلمه Adapt در لغت به معنی "وفق" دادنه ، در واقع آداپتوری (یا با تلفظ نافِ لوس آنجلسی : آداپتِر) که شما برای شارژ یا ... تون هم استفاده می‌کنید همینه ، دو تا چیز رو به هم وفق میده ، الگوی طراحی Adapter هم باز بر همین اساس ایجاد شده ، اتصال و وفق دادن دو چیزِ مختلف که شباهاتی با هم دارن .

در Adapter ما بدون تغییر در کدهای اصلی باید یک پل بین دو interface که کامل نیستند برقرار کنید مثلا یک کتاب‌خانه ، دیتا رو به صورت Xml می‌ده و شما می‌خواید اون رو به صورت Json به جای دیگه بفرستید ، با استفاده از Adapter می‌تونید این دیتا رو تبدیل کنید ، این الگو جزو طبقه Structural حساب میشه ، شِمای کلی قضیه به شکل زیره :

قراره به دشمن حمله کنیم ولی این دشمن یک دشمن خاصه که قابل حمله عادی نیست و باید حمله ما Adapt بشه و با Spell بهش حمله کنیم (به جای شمشیر و اینا مثلا :) )!
قراره به دشمن حمله کنیم ولی این دشمن یک دشمن خاصه که قابل حمله عادی نیست و باید حمله ما Adapt بشه و با Spell بهش حمله کنیم (به جای شمشیر و اینا مثلا :) )!

صورت مساله

دو Interface داریم که یکی شامل توابع پخش صوت (SoundPlayer) و دیگری توابع پخش ویدئو (MoviePlayer) ، سه شئ برای Player داریم به نام های Mp4Player که فرمت mp4 رو پخش می‌کنه ، VlcPlayer که فرمت vlc رو پخش می‌کنه و AuidoPlayer که فرمت mp3 رو پخش می‌کنه ، حالا فرض کنید ما یک MediaPlayer داریم که یک SoundPlayer رو درون خودش داره و می‌تونه با اون فرمت mp3 رو پخش کنه ولی ما می‌خوایم بتونیم با همین MediaPlayer دو فرمت دیگه رو هم پخش کنیم ، پس برای این کار به SoundAdapter نیاز داریم که implement شده از SoundPlayer هست و حالا ما می‌تونیم به جای SoundPlayer ای که قرار بوده به MediaPlayer پاس بدیم (در واقع ما AudioPlayer که یک کلاس implement شده از SoundPlayer بوده رو پاس قرار بوده بدیم) یک SoundAdapter پاس بدیم ، این طوری در override توابع تشخیص می‌دیم که اگه جنس ورودی mp3 بود که play عادی صورت بگیره وگرنه بسته به جنس یک VlcPlayer یا Mp4Player بسازیم و با اون فایل مورد نظر رو پخش کنیم .

نکته : چون جاوا و کاتلین این الگو با هم فرقی نداره من به کاتلین بسنده کردم

در قدم اول دو Interface رو مشخص می‌کنیم :

https://gist.github.com/sasssass/9b7f9a9de80c383b82a99de2f17e9b1c
https://gist.github.com/sasssass/4ccbb3fb2db4cfaca1bb8295ff936fc9

حالا نیاز داریم سه کلاس به عنوان Player ها بسازیم ، در این کلاس ها صرفا پیاده‌سازی توابع و پروتوتایپ‌های بالا قرار می‌گیرند :

https://gist.github.com/sasssass/eb753e45206f6460e9339241389bb31d
https://gist.github.com/sasssass/f3c9f4bbb9d903b930dd333a3ad9ead8
https://gist.github.com/sasssass/bbccf0667ef4817d5587c6cb3951d3ce

الان base ما ساخته شده و یک MediaPlayer می‌سازیم که بتونه صدا رو پخش کنه بنابراین این MediaPlayer به یک SoundPlayer نیاز داره ، چون SoundPlayer یه interface هست و ما از interface نمی‌تونیم به صورت مستقیم شئ بگیریم پس در کدهای جلوتر بهش یه AudioPlayer پاس می‌دیم که Implement شده از SoundPlayer هست .

https://gist.github.com/sasssass/b2610cd408a0b46ad6ca00d09a194c4d

حالا نوبت Adapter میشه ، کلاسی که implement شده از SoundPlayer هست پس می‌تونه به جای AudioPlayer به MediaPlayer پاس داده بشه ، این کلاس درون خودش مجهز به SoundPlayer و MoviePlayer هست که بسته به اینکه چه فرمتی رو بهش پاس بدیم میاد و از طریق این اشیا فرمت رو play می‌کنه

نکته : مجهز کردن این کلاس به SoundPlayer در حالی که خودش Implement شده از SoundPlayer هست کار جالبی نیست چون اصولا هدف این کلاس Adapt کردن بوده یعنی ما از قبل می‌دونیم قرار نیست بهش mp3 پاس بدیم و فقط بهش قراره mp4 و vlc پاس بدیم ولی برای اینکه خروجی کامل باشه من این کار رو انجام دادم وگرنه شخصا درست نمی‌بینم کاری که کردم رو و شاید این حرکتی که که کردم برمبنای الگویِ Adapter نباشه ولی شما این رو نادیده بگیرید !
https://gist.github.com/sasssass/a5967c407025bd422cfed3cbbea30149

در در کد نهایی ما دو کار می‌کنیم ، یه بار یک MediaPlayer درست می‌کنیم و بهش یه AudioPlayer پاس می‌دیم و یه بار که قراره بهش ویدئو پاس بدیم یه MediaPlayer درست می‌کنیم و بهش SoundAdapter رو پاس می‌دیم ، خیلی شیک !

https://gist.github.com/sasssass/34b6001d6594e95ad9360cbf82f2e0d0
نکته : آیا در RecyclerView ما از الگوی طراحی Adapter استفاده می‌کنیم ؟ اسم کلاسی که انتقال data به view رو برای ما انجام می‌ده در اینجا اسمش Adapter هست ولی در این مورد که آیا الگویِ طراحیشم Adapter حساب میشه یا نه جای بحث و بررسی وجود داره ، برخی میگن که خب این هم همین کارو می‌کنه و وفق میده پس اوکیه ولی بعضی میگن حرکتی که اینجا زده انتقال از data به view بوده و دو چیزی که Adapt شدن شبیه هم نیستن (اگه در مثالی که در این مقاله زدیم دقت کرده باشید دیدید که دو جنسی که ما Adapt کردیم با اینکه ربطی به هم ندارن ولی یک معنای مشترک دارن ، جفتشون یک چیزی رو پخش می‌کنن) و بیشتر شبیه معماری MVP می‌بینن تا الگویِ طراحی Adapter .

باقی مقالات در مورد الگوی‌های طراحی رو در این مقاله بخونید .

من رو در لینکدین و اینستاگرام دنبال کنید ???

اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???


اندرویدجاواکاتلینkotlinandroid
برنامه نویس اندروید - https://www.linkedin.com/in/iryebohs/
شاید از این پست‌ها خوشتان بیاید