9.2.1 الگو Adaptor

9.2.1 الگو Adaptor

الگو Adaptor الگوی adapter یک الگوی ساختاری است که برای سازگار کردن موجودیت های مختلف با هم به کار می‌رود.

داده ها در دنیای دیجیتال به فرمت‌های مختلف ذخیره و پردازش می‌شوند. این تفاوت در لایه‌ها و فرمت‌های مختلف نمایان و آشکار است. نمونه واضح و پرکاربرد آن فرمت‌های مختلفی مانند json و xml و باینری… است که در پروتکل‌های ارتباطی متفاوت مورد استفاده قرار می‌گیرد و گاها برای ایجاد ارتباط و امکان خوانده شدن این داده‌ها نیازمند یک روش و الگوی قابل گسترش هستیم.

الگوی adapter در اینجا مورد استفاده قرار می‌گیرد. نحوه پیاده سازی این الگو در زبان گو به اینصورت است که ابتدا یک struct مادر به همراه متد یا متدهای مورد نیاز ما که مابین موجودیت‌های متفاوت مشترک است تعریف می‌شود. همزمان برای هر فرمت داده یک struct جهت سازگار کردن داده‌ها ساخته می شود. متدهای این strcut توسط یک interface فراخوانی شده است. در اینجا کافی است که این interface را به عنوان ورودی متدهای struct مادر درنظر بگیریم. اینکار باعث ایجاد ارتباط میان struct ها و موجودیت های مختلف خواهد شد.

در زیر مثالی از پیاده سازی این الگو انجام گرفته است. در این مثال دو دستگاه پرینتر متفاوت وظیفه چاپ بر روی کاغذ با یک ابعاد خاص و مشخص (A4) را دارند در صورتی که هیچکدام بصورت اختصاصی این ابعاد را پشتیبانی نمیکنند بنابراین ما با پیاده سازی الگوی adapter این امکان را ایجاد میکنیم که این تفاوت ابعاد در داخل هر موجودیت مدیریت شود و فقط متد چاپ در ابعاد A4 فراخوانی شود.

 1package main  
 2  
 3  
 4type IPrint interface{  
 5PrintA4()  
 6}  
 7  
 8type Printer struct {}  
 9  
10func (p Printer) Print(printer IPrint) {  
11printer.PrintA4()  
12}  
13  
14// HP Printer  
15type HpPrinter struct {}  
16  
17func (h HpPrinter) PrintWithHP() {  
18println("print with HP printer")  
19}  
20  
21type HpAdapter struct {  
22printer *HpPrinter  
23}  
24  
25func (ha HpAdapter) PrintA4() {  
26println("adapting to A4 size for HP printer")  
27//some adapting functions  
28ha.printer.PrintWithHP()  
29}  
30  
31  
32// Canon Printer  
33type CanonPrinter struct {}  
34  
35func (c CanonPrinter) PrintWithCanon() {  
36println("print with Canon printer")  
37}  
38  
39type CanonAdapter struct{  
40printer *CanonPrinter  
41}  
42  
43func (ca CanonAdapter) PrintA4() {  
44println("adapting to A4 size for Canon printer")  
45//some adapting functions  
46ca.printer.PrintWithCanon()  
47}  
48  
49  
50func main() {  
51  
52  
53hpPrinter := &HpPrinter{}  
54hpAdapter := HpAdapter{  
55printer: hpPrinter,  
56}  
57  
58canonPrinter := &CanonPrinter{}  
59canonAdapter := CanonAdapter{  
60printer: canonPrinter,  
61}  
62  
63printer := Printer{}  
64printer.Print(hpAdapter)  
65printer.Print(canonAdapter)  
66}
1
2adapting to A4 size for HP printer
3print with HP printer
4adapting to A4 size for Canon printer
5print with Canon printer

۱− در مثال بالا ما برای هر پرینتر یک struct به عنوان adapter ایجاد کرده ایم (خطوط 21 و 39) ۲− این struct ها متدی به نام PrintA4 را تعریف می‌کنند‌ که وظیفه تغییر داده ها به فرمت مشترک مورد نظر را دارند (خطوط 25 و 43) ۳− این متد در یک اینترفیس به نام IPrint نیز فراخوانی می‌شود (خط 5) ۴− در این مرحله یک struct به نام Printer ایجاد میکنیم (خط 8) ۵− در مرحله آخر متد اصلی که وظیفه Print کردن کاغذ برای هر پیرنتری را دارد تعریف میکنیم. نکته مهم ورودی این متد است که همان interface تعریف شده در مرحله 3 می باشد. ۶− مرحله آخر تغریف هر پرینتر و printerAdapter در خطوط 52 تا 61 است و درنهایت فراخوانی متد تعریف شده در مرحله 5 برای هر پرینتر در خطوط 64 و 65.