کلمه Adapt در لغت به معنی "وفق" دادنه ، در واقع آداپتوری (یا با تلفظ نافِ لوس آنجلسی : آداپتِر) که شما برای شارژ یا ... تون هم استفاده میکنید همینه ، دو تا چیز رو به هم وفق میده ، الگوی طراحی Adapter هم باز بر همین اساس ایجاد شده ، اتصال و وفق دادن دو چیزِ مختلف که شباهاتی با هم دارن .
در Adapter ما بدون تغییر در کدهای اصلی باید یک پل بین دو interface که کامل نیستند برقرار کنید مثلا یک کتابخانه ، دیتا رو به صورت Xml میده و شما میخواید اون رو به صورت Json به جای دیگه بفرستید ، با استفاده از Adapter میتونید این دیتا رو تبدیل کنید ، این الگو جزو طبقه Structural حساب میشه ، شِمای کلی قضیه به شکل زیره :
دو 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 رو مشخص میکنیم :
حالا نیاز داریم سه کلاس به عنوان Player ها بسازیم ، در این کلاس ها صرفا پیادهسازی توابع و پروتوتایپهای بالا قرار میگیرند :
الان base ما ساخته شده و یک MediaPlayer میسازیم که بتونه صدا رو پخش کنه بنابراین این MediaPlayer به یک SoundPlayer نیاز داره ، چون SoundPlayer یه interface هست و ما از interface نمیتونیم به صورت مستقیم شئ بگیریم پس در کدهای جلوتر بهش یه AudioPlayer پاس میدیم که Implement شده از SoundPlayer هست .
حالا نوبت Adapter میشه ، کلاسی که implement شده از SoundPlayer هست پس میتونه به جای AudioPlayer به MediaPlayer پاس داده بشه ، این کلاس درون خودش مجهز به SoundPlayer و MoviePlayer هست که بسته به اینکه چه فرمتی رو بهش پاس بدیم میاد و از طریق این اشیا فرمت رو play میکنه
نکته : مجهز کردن این کلاس به SoundPlayer در حالی که خودش Implement شده از SoundPlayer هست کار جالبی نیست چون اصولا هدف این کلاس Adapt کردن بوده یعنی ما از قبل میدونیم قرار نیست بهش mp3 پاس بدیم و فقط بهش قراره mp4 و vlc پاس بدیم ولی برای اینکه خروجی کامل باشه من این کار رو انجام دادم وگرنه شخصا درست نمیبینم کاری که کردم رو و شاید این حرکتی که که کردم برمبنای الگویِ Adapter نباشه ولی شما این رو نادیده بگیرید !
در در کد نهایی ما دو کار میکنیم ، یه بار یک MediaPlayer درست میکنیم و بهش یه AudioPlayer پاس میدیم و یه بار که قراره بهش ویدئو پاس بدیم یه MediaPlayer درست میکنیم و بهش SoundAdapter رو پاس میدیم ، خیلی شیک !
نکته : آیا در RecyclerView ما از الگوی طراحی Adapter استفاده میکنیم ؟ اسم کلاسی که انتقال data به view رو برای ما انجام میده در اینجا اسمش Adapter هست ولی در این مورد که آیا الگویِ طراحیشم Adapter حساب میشه یا نه جای بحث و بررسی وجود داره ، برخی میگن که خب این هم همین کارو میکنه و وفق میده پس اوکیه ولی بعضی میگن حرکتی که اینجا زده انتقال از data به view بوده و دو چیزی که Adapt شدن شبیه هم نیستن (اگه در مثالی که در این مقاله زدیم دقت کرده باشید دیدید که دو جنسی که ما Adapt کردیم با اینکه ربطی به هم ندارن ولی یک معنای مشترک دارن ، جفتشون یک چیزی رو پخش میکنن) و بیشتر شبیه معماری MVP میبینن تا الگویِ طراحی Adapter .
باقی مقالات در مورد الگویهای طراحی رو در این مقاله بخونید .
من رو در لینکدین و اینستاگرام دنبال کنید ???
اگه دوست داشتید میتونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???