
این Pattern جز دسته ی Structural از مجموعه GOF میباشد. هدف از ارائه الگوی Adapter ، تبدیل Interface یک Class به Interface ی که مورد انتظار Client است، میباشد. در واقع الگوی Adapter روشی است که بوسیله آن میتوان کلاسهایی با Interface متفاوت را در یک سیستم کنار یکدیگر مورد استفاده قرار داد.
به بیان سادهتر اگر بخواهیم از کلاسهای نامنطبق (کلاسهای غیر مرتبط) در یک سیستم استفاده کنیم، راه حل مناسب استفاده از الگوی Adapter میباشد. از الگوی Adapter را به عنوان یک Wrapper یاد می شود.
الگوی Adapter از سه Component مهم تشکیل شده است،که عبارتند از:
- Target
- Adapter
- Adaptee
Target
کلاس یا Interface ی است که توسط Client مورد استفاده قرار میگیرد، و Client از طریق آن درخواستهای خود را بیان میکند. در واقع Functionality موجود در کلاس Target به جهت پاسخگویی به درخواستهای Client فراهم گردیده است. در بعضی منابع به آن کلاس Service هم می گویند.
Adaptee
کلاسی است، دارای قابلیتهای مورد نیاز Client بطوریکه Interface اش با Interface مورد انتظار Client (یعنی Target)سازگار نیست. و Client برای استفاده از امکانات کلاس Adaptee و سازگاری با Interface مورد انتظارش نیاز به یک Wrapper همانند کلاسAdapter دارد.
Adapter
کلاسی است که قابلیتها و امکانات کلاس Adaptee را با Interface مورد انتظار Client یعنی Target سازگار میکند، تا Client بتواند از امکانات کلاس Adaptee جهت رفع نیازهای خود استفاده نماید. به بیان سادهتر Adapter کلاسی هست که برای اتصال دو کلاس با اینترفیس متفاوت مورد استفاده قرار میگیرد.
برای رعایت اصل open-close principle ، نباید تغییری در Target و Client ایجاد شود؛ بدیهی است که Adaptee که از وجود Adapter آگاه نیست و Adapter باید همان Target که Client انتظار دارد را به کمک کلاس Adaptee پیاده سازی کند و در اختیار کلاس Client قرار دهد. این کمک گرفتن از کلاس Target به دو صورت می باشد:
- (Class Adapter): ارث بری کردن از کلاس Target یا همان Service توسط Adapter
در این روش کلاس Adapter از ارث بری چند گانه استفاده میکند و Interface مرتبط به Adaptee را به Interface مرتبط به Target سازگار مینماید.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Program { static void Main(string[] args) { ITarget target = new Adapter(); target.Request(); Console.ReadKey(); } } interface ITarget { void Request(); } class Adaptee { public void SpecificationRequest() { Console.WriteLine("SpecificationRequest() is called"); } } class Adapter : Adaptee, ITarget { public void Request() { SpecificationRequest(); } } |
متد SpecificationRequest واقع در Adaptee میتواند نیاز Client را برطرف نماید، اما Client، چیزی را که مشاهده میکند اینترفیس ITarget میباشد، به عبارت دیگر Client بطور مستقیم نمیتواند با Adaptee ارتباط برقرار کند، بنابراین اگر بخواهیم از طریق ITarget نیاز Client را برطرف نماییم، لازم است کلاسی بین I،arget و Adaptee به جهت تبادل اطلاعات ایجاد کنیم، که Adapter نامیده میشود. حال در روش Class Adapter، کلاس Adapter جهت تبادل اطلاعات بین ITarget و Adaptee هر دو را در خود Implement مینماید.
2. (Object Adapter): ایجاد یک شی از service یا Target درون کلاس adapter
در زبان برنامه نویسی #C هر کلاس فقط میتواند از یک کلاس دیگر مشتق شود، و نمیتواند بیش از یک کلاس Parent داشته باشد، بنابراین اگر Client بخواهد از امکانات و قابلیتهای چندین کلاس Adaptee استفاده نماید، روش Class Adapter نمیتواند پاسخگو باشد، در این صورت باید از روش Object Adapter استفاده کرد.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Program { static void Main(string[] args) { ITarget target = new Adapter(); target.Request(); Console.ReadKey(); } } class Adaptee { public void SpecificRequest() { Console.WriteLine("SpecificRequest() is called"); } } interface ITarget { void Request(); } class Adapter : ITarget { private Adaptee _adaptee = new Adaptee(); public void Request() { _adaptee.SpecificRequest(); } } |
در کد بالا به جای ارث بری از کلاس Adaptee ، آبجکت آن را ایجاد کردیم. واضح است که Object Adapter انعطاف پذیرتر نسبت به Class Adapter میباشد.
کاربردها
- زمانی از الگوی Adapter استفاده میکنیم که کلاسـی وجود داشته باشد که بخواهـیم از آن استـفاده کنیم، اما Interface آن با مابقی کد ما تطابق نداشته باشد. الگوی Adapter یک لایه میانی به عنوان مترجم بین کد ما و کلاس مورد نظر ایجاد میکند.(Wrapper)
- زمانی که ما Subclass هایی از یک کلاس والد داریم که نیاز است یک عمل جدیدی به آنها اضافه کنیم. از طرفی کلاس والد مذکور برای این امر بسته است و نمیتوانیم این کار را از طریق اضافه کردن کد مورد نظر به آن انجام دهیم. یک راه این است که متد مورد نظر را به تک تک Subclass های موجود اضافه کنیم که این کار به دلیل تکرار کد نویسی پسندیده نمیباشد. راه دیگر این است که یک Adapter ایجاد کنیم و Subclass مورد نظر را در آن قرار دهیم و به صورت Dynamic رفتار مورد نظر را به عمل Subclass ها اضافه کنیم. توجه شود Adapter همان Interface ای را پیاده میکند که بین همه subclass ها مشترک است.