میتونین برای آشنایی با الگوهای طراحی (یا همون دیزاین پترن های) زبان جاوا به مقاله ی مراجعه کنین. (همونطور که گفته شده این الگو زیرمجموعه ی الگوهای ساختاری ( Structural ) هست) بذارین با اسم این الگو شروع کنیم. آداپتور! همونجوری که توی واقعیت عمل میکنه، اینجا هم یه آداپتور به دو رابط ناسازگار اجازه میده تا بتونن با هم کار کنن. این یه تعریف کلی از مفهوم آداپتوره. ممکنه رابط ها ناسازگار باشن ولی قابلیت درونی آنها باید سازگار با نیاز باشن. به عبارت دیگه، الگوی طراحی آداپتور، به کلاسای ناسازگار اجازه میده تا بتونن از قابلیت‌های همدیگه استفاده کنن. چیزی که در ساخت آداپتور مهمه اینه که لازم نیست رفتار شی رو تغییر بدیم و تنها چیزی که لازمه اینه که آداپتوری ایجاد کنیم که بتونه با کلاسایی که باید، ارتباط برقرار کنه. بصورت خلاصه میشه گفت: طبیعتا این الگو نه تنها امکان استفاده مجدد از اعمال رو به هر صورت که بخوایم بهمون میده، بلکه از بازنویسی کدای مربوط به اعمال خاص، که قصد استفاده از اونا رو در مکان دیگری داریم هم جلوگیری میکنه. خب حالا که با مفهوم این الگو آشنا شدیم، فرض کنیم میخوایم به نرم افزار ساده برای بانک بنویسیم. با کلاسی به اسم BankDetails شروع میکنیم که اطلاعات حساب یه شخص به همراه شماره حساب و نامش رو ذخیره میکنه: حالا میایم به اینتر فیس به اسم CreditCard بصورت زیر مینویسیم: همونطور که میبینیم این اینترفیس شامل تابع generateBankDetails که باید جزییات بانک رو بسازه، و getCreditCard که جزییات کارت اعتباری رو برگردونه میشه. کلاس بعدی ای که مینویسیم BankCustomer هست که اطلاعات بانکی و کارت اعتباری ( Credit Card ) رو نگه میداره: همونطور که میبینیم این کلاس از BankDetails ارث برده و اینترفیس CreditCard رو پیاده سازی کرده. و تمام! ما یه مثال ساده از الگوی Adapter رو پیاده سازی کردیم. برای تست خروجی، کدهای زیر رو مینویسیم: اتفاقی که اینجا افتاده به این صورته که کلاس BankCustomer از کلاس BankDetails ارث میبره و اینترفیس CreditCard رو پیاده میکنه. در حقیقت توی این مثال ما یه کلاس مشتری میخواستیم که اسمشو BankCustomer گذاشتیم، ولی این کلاس در عین اینکه کاملا به کلاس BankDetails وابستس، باید ازش مجزا باشه، به همین خاطر اینترفیس CreditCard رو نوشتیم. بذارین برای اینکه این مفهوم بهتر جا بیفته، یه مثالی بزنیم که هر دو نوع وابستگی این الگو (که بر اساس شی یا بر اساس کلاس هست) رو شامل بشه. میخوایم دیاگرام زیر رو پیاده سازی بکنیم: میخوایم برنامه ای برای آداپتورای توی دنیای واقعی بنویسیم. با کلاس ولتاژ شروع میکنیم: و کلاسی به اسم Socket که طبیعتا هر سوکتی لتاژ خودش رو داره (و بصورت پیشفرض ولتاژ رو در نظر میگیریم) : و یه اینترفیس یا همون آداپتور به اسم SocketAdapter تعریف میکنیم: تا اینجا زیرساخت پیاده سازی الگوی Adapter رو نوشتیم. اینجا دو راه جلومونه، یکی پیاده سازی بر اساس شی و یکی پیاده سازی بر اساس کلاس! اول ببینیم اگه بخوایم بر اساس کلاس پیاده سازی کنیم چه ساختاری باید داشته باشیم: همونطور که میبینیم توی این حالت کلاسمون از Socket ارث برده و SocketAdapter رو پیاده سازی کرده. و اگه بخوایم این ساختار بر اساس شی پیاده سازی بشه به شکل زیر عمل میکنیم: همونطور که میبینیم این کلاس فقط اینترفیس SocketAdapter رو پیاده کرده. در حقیقت بر خلاف روش قبلی، بجای ارث بردن از کلاس Socket ، یه آبجکت از این کلاس رو نگداری میکنه (که عملا اینجا تنها تفاوت دو روش و همینه) حالا کافیه برای تست تابعی به شکل زیر بنویسیم: برای تست حالت اول این قطعه کد رو بنویسیم: و برای تست حالت دوم این قطعه کد رو مینویسیم: همون طور که میبینیم، چیزی که ما موقع استفاده میبینیم (نحوه ی تعریف شی و صدا کردن توابع هر دو کلاس SocketObjectAdapterImpl SocketClassAdapterImpl ) دقیقا یکیه. نتایج خروجی تست ها هم بصورت زیره: به عنوان توضیح تکمیلی و برای مشخص تر شدن اینکه چه اتفاقی افتاد، میتونی بگیم که ما دو تا کلاس داشتیم، یکی ولتاژ و اون یکی سوکت. هر سوکت با اینکه کلاسش باید مجزا از کلاس ولتاژ میبود، خودش یه ولتاژ نیاز داشت. پس اومدیم از اینترفیس SocketAdapter استفاده کردیم تا به عنوان یجور واسطه بین این کلاس ها عمل کنه، و با توجه نوع پیاده سازی ساختارمون کلاس های SocketObjectAdapterImpl و SocketClassAdapterImpl رو پیاده سازی کردیم. ساختار الگوی پیچیده نیست، فقط باید یذره تمرین کنیم تا به مرور زمان متوجه شیم که کی و کجا باید ازش استفاده بشه. این پترن تا حدودی شبیه پترن هست و ممکنه با دیدن این دو پترن کمی گیج بشین. باید دقت کنیم که از الگوی Adapter برای کار کردن با کلاس های ناهمسازگار استفاده میشه که قابلیت های یکسانی دارن، ولی اسم متدها یا نوع بازگشتیشون فرق داره. از طرفی، از الگوی Bridge زمانی استفاده میشه که نیاز داریم بین متدهای انتزاعی و پیاده سازی های مختلف یکی رو انتخاب کنیم، و هم متدهای انتزاعی و هم پیاده سازی اونا به صورت مستقل از هم بروزرسانی بشن. منتشر شده در توسط این وبسایت : virgool . io / @ mohammad . ghodsian