حوزه: Object / Class
هدف: Structural
نقش الگو
همان گونه که از اسم این الگو مشخص است، هنگامی که دو کلاس واسط(Interface) های غیرمرتبط با یکدیگر داشته باشند این الگو واسط یکی را به دیگری تبدیل میکند که بتوانند با یکدیگر ارتباط برقرار کند. از این الگو که یک الگوی ساختاری است زمانی استفاده میشود که بخواهیم در یک برنامه، دو کلاس غیرمرتبط با یکدیگر کار کنند. این الگو در برنامههایی که از کلاسهای آماده استفاده میشود و یا از کلاسهایی استفاده میشود که قبلا نوشته شدهاند و به گونهای باشد که طراحان نرم افزار اجازه تغییر در این کلاسها را نداشته باشند، استفاده میشود.
الگوی Adapter انواع مختلفی دارد که فهرست آنها به شرح ذیل میباشد:
ساختار این الگو به این شکل است:
همانطور که در شکل دیده میشود کلاس Adapter از اینترفیس ITarget مشتق شده است و در یکی از متدهایی که در این کلاس وجود دارد (Request) متد مورد نظر را از کلاس Adaptee فراخوانی میکند. کلاس Adapter متدهای Adaptee را با متدها و خصوصیات Target وفق می دهد. به طور کلی اینترفیس ITarget همان اینترفیسی است که کاربر آن را پیاده سازی میکند و کلاس Adaptee همان کلاسی است که باید با برنامه وفق داده شود. کاربران برای استفاده فقط از کلاس Adapter نمونه سازی میکنند و نیازی به درگیری با ارتباط Target و Adaptee نخواهند بود.
کد این الگو به شرح زیر است.
Adapter دوطرفه
ساده ترین شکل الگوی Adapter شکل یک طرفه آن است که یک کلاس یا اینترفیس Target بوده و کلاس دیگر نقش Adaptee را داشت که تا این قسمت شرح داده شد. حال فرض کنید که میخواهیم هر دو طرف هم نقش Adaptee و هم نقش Target را داشته باشند. به گونهای که از کلاس Adapter بتوان همه به شکلی استفاده کرد که متدهای هر دو طرف را داشته باشند. در این صورت کلاس Adapter دارای متدها و خصوصیات هر دو کلاس میباشد. یک Adapter دو طرفه میتواند به جای هر دو کلاس Target و Adaptee مورد استفاده قرار بگیرد. برای این کار در زبانهایی مانند ++C که وراثت از چندین کلاس را پشتیبانی میکنند کار آسانی است. به این شکل که کلاس Adapter از دو کلاس دیگر ارث بری داشته باشد، همانند ساختار زیر:
اما در بسیاری از زبان های برنامه نویسی رایج مانند #C و Java ارث بری از چندکلاس پشتیبانی نمیشود. بنابراین، این راه حل در این زبانها پاسخگو نیست. برای این که در این زبانها از Adapter دو طرفه استفاده کنیم به شکل زیر عمل می کنیم.
تفاوت حوزه های Object و Class
Object: در این روش ناسازگاری با ایجاد یک شی برطرف میشود. در این روش کلاس Adapter به جای ارث بری از کلاس Adaptee یک Object از کلاس Adaptee را در خود ایجاد میکند. بنابراین شما میتوانید به چندین کلاس Adaptee توسط کلاس Adapter دسترسی داشته باشید.
Class: در این روش ناسازگاری با وراثت بین کلاسها برطرف می شود. به بیان دیگر کلاس Adapter از ارث بری چندگانه استفاده میکند و اینترفیسهای کلاسهای Target و Adaptee را با هم سازگار می کند.
هدف: Structural
نقش الگو
همان گونه که از اسم این الگو مشخص است، هنگامی که دو کلاس واسط(Interface) های غیرمرتبط با یکدیگر داشته باشند این الگو واسط یکی را به دیگری تبدیل میکند که بتوانند با یکدیگر ارتباط برقرار کند. از این الگو که یک الگوی ساختاری است زمانی استفاده میشود که بخواهیم در یک برنامه، دو کلاس غیرمرتبط با یکدیگر کار کنند. این الگو در برنامههایی که از کلاسهای آماده استفاده میشود و یا از کلاسهایی استفاده میشود که قبلا نوشته شدهاند و به گونهای باشد که طراحان نرم افزار اجازه تغییر در این کلاسها را نداشته باشند، استفاده میشود.
الگوی Adapter انواع مختلفی دارد که فهرست آنها به شرح ذیل میباشد:
- Class Adapter
- Object Adapter
- Two way Adapter
- Pluggable Adapter
ساختار این الگو به این شکل است:
همانطور که در شکل دیده میشود کلاس Adapter از اینترفیس ITarget مشتق شده است و در یکی از متدهایی که در این کلاس وجود دارد (Request) متد مورد نظر را از کلاس Adaptee فراخوانی میکند. کلاس Adapter متدهای Adaptee را با متدها و خصوصیات Target وفق می دهد. به طور کلی اینترفیس ITarget همان اینترفیسی است که کاربر آن را پیاده سازی میکند و کلاس Adaptee همان کلاسی است که باید با برنامه وفق داده شود. کاربران برای استفاده فقط از کلاس Adapter نمونه سازی میکنند و نیازی به درگیری با ارتباط Target و Adaptee نخواهند بود.
کد این الگو به شرح زیر است.
public class Adaptee {
public double specificRequest(double a, double b) {
return a / b;
}
}
public interface ITarget {
String request(int a);
}
public class Adapter extends Adaptee implements ITarget {
public String request(int a) {
return "the result is" + (int) Math.round(specificRequest(a, 5));
}
}
Adapter دوطرفه
ساده ترین شکل الگوی Adapter شکل یک طرفه آن است که یک کلاس یا اینترفیس Target بوده و کلاس دیگر نقش Adaptee را داشت که تا این قسمت شرح داده شد. حال فرض کنید که میخواهیم هر دو طرف هم نقش Adaptee و هم نقش Target را داشته باشند. به گونهای که از کلاس Adapter بتوان همه به شکلی استفاده کرد که متدهای هر دو طرف را داشته باشند. در این صورت کلاس Adapter دارای متدها و خصوصیات هر دو کلاس میباشد. یک Adapter دو طرفه میتواند به جای هر دو کلاس Target و Adaptee مورد استفاده قرار بگیرد. برای این کار در زبانهایی مانند ++C که وراثت از چندین کلاس را پشتیبانی میکنند کار آسانی است. به این شکل که کلاس Adapter از دو کلاس دیگر ارث بری داشته باشد، همانند ساختار زیر:
اما در بسیاری از زبان های برنامه نویسی رایج مانند #C و Java ارث بری از چندکلاس پشتیبانی نمیشود. بنابراین، این راه حل در این زبانها پاسخگو نیست. برای این که در این زبانها از Adapter دو طرفه استفاده کنیم به شکل زیر عمل می کنیم.
public class Adaptee {در کد بالا یکی از اینترفیس ها (IAircraft ) که همان Target است را در کلاس Adapter پیاده سازی میکنیم و از کلاس Adaptee ارث بری مینماییم. ساختار این عمل شبیه به همان استفاده از الگوی Adapter به شکل یک طرفه آن است ولی در استفاده به این شکل عمل میکنیم. همانطور که مشاهده میشود می توان از کلاس Adapter هم به عنوان یک نمونه از Target و هم به عنوان یک نمونه از Adaptee استفاده نمود. مشکلی که در زبان هایی مانند C# یا Java وجود دارد این است که باید Target را به عنوان اینترفیس معرفی کرده و در کلاس Adapter آن را پیاده سازی نمود ولی در زبانی مانند C++ چنین محدودیتی وجود ندارد.
public double specificRequest(double a, double b) {
return a / b;
}
}
public interface ITarget {
String request(int a);
}
public class Adapter extends Adaptee implements ITarget {
public String request(int a) {
return "the result is, " + (int) Math.round(specificRequest(a, 5));
}
}
public class App {
public static void main(String[] args) {
Adapter adapter = new Adapter();
System.out.println(adapter.request(5));
System.out.println(adapter.specificRequest(5, 5));
}
}
تفاوت حوزه های Object و Class
Object: در این روش ناسازگاری با ایجاد یک شی برطرف میشود. در این روش کلاس Adapter به جای ارث بری از کلاس Adaptee یک Object از کلاس Adaptee را در خود ایجاد میکند. بنابراین شما میتوانید به چندین کلاس Adaptee توسط کلاس Adapter دسترسی داشته باشید.
Class: در این روش ناسازگاری با وراثت بین کلاسها برطرف می شود. به بیان دیگر کلاس Adapter از ارث بری چندگانه استفاده میکند و اینترفیسهای کلاسهای Target و Adaptee را با هم سازگار می کند.
مثال پیاده سازی شده با زبان جاوا را میتوانید از github من دانلود کنید.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.