# نمط المحول

في هندسة البرمجيات، نمط المحوّل (بالإنجليزية: adapter pattern)‏ هو نمط تصميم برمجيات (يُعرف أيضًا باسم المغلّف؛ تسمية بديلة مشتركة مع نمط الديكور) يسمح لواجهة صنف موجود مسبقاً ليُستخدم كواجهة أخرى. غالبًا ما يتم استخدامه لجعل الأصناف الموجودة تعمل مع الآخرين دون تعديل الكود المصدري الخاص بهم.
مثال على ذلك هو المحوّل الذي يحوّل واجهة نموذج كائن المستند من مستند XML إلى بنية شجرة يمكن عرضها.

## نظرة عامة

يعد نمط تصميم المحوّل أحد أنماط تصميم GoF الثلاثة والعشرون المعروفة التي تصف كيفية حل مشاكل التصميم المتكررة لتصميم برنامج مرن وقابل لإعادة الاستخدام، أي ذو توجيه كائني الذي يسهل تنفيذه، تغييره، اختباره وإعادة استخدامه.
يحل نمط تصميم المحوّل مشاكل مثل:
* كيف يمكن إعادة استخدام صنف (بالإنجليزية: class)‏ لا يحتوي على واجهة يطلبها العميل؟
* كيف يمكن للأصناف التي تحتوي على واجهات غير متوافقة أن تعمل معًا؟
* كيف يمكن تُوفّر واجهة بديلة لصنف؟
غالبًا لا يمكن إعادة استخدام صنف (موجود بالفعل) فقط لأن واجهته لا تتوافق مع الواجهة التي يطلبها العملاء.
يصف نمط تصميم المحوّل كيفية حل مثل هذه المشاكل:
* عرّف صنف محوّل منفصل (بالإنجليزية: adapter)‏ يحول الواجهة (غير المتوافقة) للصنف المحَوَل (بالإنجليزية: adaptee)‏ إلى واجهة أخرى تُعتبر الهدف (بالإنجليزية: target)‏ والتي يطلبها العملاء.
* اعمل من خلال محوّل (بالإنجليزية: adapter)‏ للعمل مع (إعادة استخدام) أصناف ليس لها الواجهة المطلوبة.
الفكرة الرئيسية في هذا النمط هي العمل من خلال المحوّل المنفصل (بالإنجليزية: adapter)‏، الذي يقوم بتكييف (تحويل) واجهة صنف (موجودة مسبقاً) دون تغييرها.
لا يعرف العملاء إذا ما كانوا يعملون مع الصنف الهدف مباشرة (بالإنجليزية: target)‏ أم من خلال محوّل (بالإنجليزية: adapter)‏ مع صنف لا يحتوي على الواجهة الهدف (بالإنجليزية: target)‏.
انظر أيضًا الرسم التخطيطي للصنف بلفة النمذجة الموحدة أدناه.

## تعريف

يسمح المحوّل لواجهتين غير متوافقتين بالعمل معًا. هذا هو التعريف الحقيقي للمحوّل. قد تكون الواجهات غير متوافقة، ولكن الوظيفة الداخلية يجب أن تلبي الحاجة. يسمح نمط تصميم المحوّل للأصناف غير المتوافقة بالعمل معًا من خلال تحويل واجهة إحدى الأصناف إلى واجهة يتوقعها العملاء.

## استخدام

يمكن استخدام المحوّل عندما يتوجب على المُغلّف الالتزام بواجهة معينة ويجب أن يدعم سلوك متعدد الأشكال. بدلاً من ذلك، منفذ نمط الديكور يمكّن من إضافة أو تغيير سلوك واجهة في وقت التشغيل، ويتم استخدام واجهة البناء عند الرغبة في واجهة أسهل أو أبسط لكائن أساسي.
| نمط | نوايا |
| محوّل أو مُغلّف | يحول واجهة إلى أخرى بحيث تتطابق مع ما يتوقعه العميل. |
| منفذ الديكور | يضيف المسؤولية إلى الواجهة ديناميكيًا من خلال تغليف الكود الأصلي. |
| تفويض | دعم "التركيب على الميراث". |
| واجهة البناء | يوفر واجهة بينية مبسطة. |

## هيكل
### مخطط الصنف بلغة النمذجة الموحدة

في مخطط الصنف بلغة النمذجة الموحدة أعلاه، لا يمكن لصنف العميل (بالإنجليزية: client)‏ الذي يتطلب الواجهة الهدف (بالإنجليزية: target)‏ إعادة استخدام صنف المحَوَل (بالإنجليزية: adaptee )‏ مباشرة لأن المحوَل (بالإنجليزية: adaptee)‏ لا يتوافق مع الواجهة الهدف (بالإنجليزية: target)‏ . بدلاً من ذلك، يقوم العميل (بالإنجليزية: client)‏ خلال صنف المحوّل (بالإنجليزية: adapter)‏ بتنفيذ الواجهة الهدف (بالإنجليزية: target)‏ من حيث المحوَل (بالإنجليزية: adaptee)‏ :
* أسلوب مُحوّل الكائن (بالإنجليزية: object adapter)‏ ينفذ الواجهة الهدف (بالإنجليزية: target)‏ عن طريق التفويض إلى كائن محَوَل (بالإنجليزية: adaptee)‏ في وقت التشغيل (بالإنجليزية:adaptee.specificOperation)‏ (الكود: محَوَل.عملية محددة).
* أسلوب مُحوّل الصنف (بالإنجليزية: class adapter)‏ ينفذ الواجهة الهدف (بالإنجليزية: target)‏ من خلال الوراثة من صنف المحَوَل (بالإنجليزية: adaptee)‏ في وقت التجميع (بالإنجليزية:specificOperation)‏ (الكود: عملية محددة).

### نمط محوّل الكائن

نمط محوّل الكائن (بالإنجليزية: Object adapter pattern)‏ في نمط المحوّل هذا، يحتوي المحوّل على مثيل من الصنف الذي يغلّفه. في هذه الحالة، يقوم المحوّل بإجراء استدعاءات إلى مثيل الكائن المُغلّف.

### نمط محوّل الصنف

نمط محوّل الصنف (بالإنجليزية: Class adapter pattern)‏ يستخدم نمط المحوّل هذا عدة واجهات متعددة الأشكال تقوم بتنفيذ أو توريث كل من الواجهة المتوقعة والواجهة الموجودة مسبقًا. من المعتاد أن تكون الواجهة المتوقعة مُنشئة كصنف واجهة خالصة (صافية)، خاصة في لغات مثل جافا (قبل JDK 1.8) التي لا تدعم توارث الأصناف المتعدد.

### شكل آخر من أنماط محوّل وقت التشغيل
#### الدافع من الحل وقت التجميع

يجب أن يدعم صنف ClassA صنف classB مع بعض البيانات، لنفترض وجود بعض البيانات من سلاسل النصString . الحل وقت التجميع هو التالي:
ومع ذلك، افترض أنه يجب تغيير تنسيق بيانات السلاسل النصية في String . الحل وقت التجميع هو استخدام الوراثة:
وربما إنشاء كائن «التنسيق» بشكل صحيح في وقت التشغيل عن طريق نمط المصنع.

#### حل محوّل وقت التشغيل

باستخدام «المحوّلات» نحصل على الحل كما يلي:
1. عرّف واجهة «مزود» وسيط، واكتبْ تنفيذ لواجهة المزود تلك التي تغلف مصدر البيانات، ClassA في هذا المثال، وتخرج البيانات المنسقة حسب الضرورة:
2. اكتبْ صنف محوّل الذي يرجع التنفيذ المحدد للمزود:
3. سجّلْ المحوّل adapter في سجل عالمي، بحيث يمكن البحث عن المحوّل adapter في وقت التشغيل:
4. في الكود، عند الرغبة في نقل البيانات من صنف ClassA إلى صنف classB ، اكتبْ:
أو بشكل أكثر إيجازًا:
5. يمكن ملاحظة الفائدة من ذلك، إذا كان من المطلوب نقل البيانات بتنسيق ثاني، فابحثْ عن المحوّل/ المزود المختلف:
6. وإذا كان من المطلوب إخراج البيانات من صنف ClassA ، على سبيل المثال؛ بيانات لصورة في ClassC :
7. بهذه الطريقة، استخدام المحوّلات والمزودين يسمح بتعدد «الرؤية» من قبل صنفا ClassB و ClassC في صنف ClassA دون الحاجة إلى تغيير التسلسل الهرمي للأصناف. بشكل عام، ما سبق يسمح بآلية لتدفق البيانات الغير محددة بين الكائنات التي يمكن تعديلها إلى التسلسل الهرمي للكائن الموجود.

### تنفيذ نمط المحوّل

عند تنفيذ نمط المحوّل، للتوضيح، يمكن للمرء تطبيق اسم الصنف من صنف إلى واجهة محوّل كالتالي [ClassName]To[Interface]Adapter للتنفيذ الخاص بالمزود، على سبيل المثال DAOToProviderAdapter . يجب أن يكون لديه طريقة المنشئ مع متغير خاص بصنف المحَوَل كمعلمة. سيتم تمرير هذه المعلمة إلى مثيل عضو instance member of من (اسم-الصنف) إلى (اسم-الواجهة) للمحوّل كالتالي [ClassName]To[Interface]Adapter . عندما يتم استدعاء طريقة العميل، سيتمكن من الوصول إلى مثيل المحوَل الذي يسمح بالوصول إلى البيانات المطلوبة للمحوَل وتنفيذ العمليات على تلك البيانات التي تولد المخرجات المطلوبة.

#### كريستال

المخرجات:
Recharging android with MicroUsb Recharger MicroUsb connected
Recharge started Recharge finished

#### جافا

مخرجات:
Recharging android with MicroUsb
Recharge started Recharge finished

#### دلفي

المخرجات:
Recharging android with MicroUsb
Recharge finished