الفرق بين المراجعتين لصفحة: «Refactoring/hide delegate»
جميل-بيلوني (نقاش | مساهمات) ط تصغير الصور. |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة وتدقيق. |
||
سطر 9: | سطر 9: | ||
==== قبل إعادة التصميم ==== | ==== قبل إعادة التصميم ==== | ||
يتعامل صنف العميل (client class) مع صنفين، الأول صنف الأقسام (Department) والثاني صنف الأشخاص (Person) واللذان يحتويان تابعين للحصول على كائنٍ (object) من الصنف الآخر (وهما التابعان getManager و getDepartment)، كما في المخطط الآتي: | يتعامل صنف العميل (client class) مع صنفين، الأول صنف الأقسام (Department) والثاني صنف الأشخاص (Person) واللذان يحتويان تابعين للحصول على كائنٍ (object) من الصنف الآخر (وهما التابعان <code>getManager</code> و <code>getDepartment</code>)، كما في المخطط الآتي: | ||
[[ملف:Hide-Delegate-Before.png|بديل=مخطط يوضح كيف يتعامل صنف العميل مع الصنفين Person و Department مباشرةً.|بدون|مخطط يوضح كيف يتعامل صنف العميل مع الصنفين Person و Department مباشرةً.|تصغير]] | [[ملف:Hide-Delegate-Before.png|بديل=مخطط يوضح كيف يتعامل صنف العميل مع الصنفين Person و Department مباشرةً.|بدون|مخطط يوضح كيف يتعامل صنف العميل مع الصنفين <code>Person</code> و <code>Department</code> مباشرةً.|تصغير]] | ||
==== بعد إعادة التصميم ==== | ==== بعد إعادة التصميم ==== | ||
أصبح تعامل صنف العميل مع صنفٍ واحدٍ فقط (وهو الصنف Person) والذي بدوره سينتقل (delegate) إلى الصنف الآخر Department دون إرباك العميل بتفاصيل ذلك، كما هو واضح في المخطط: | أصبح تعامل صنف العميل مع صنفٍ واحدٍ فقط (وهو الصنف <code>Person</code>) والذي بدوره سينتقل (delegate) إلى الصنف الآخر <code>Department</code> دون إرباك العميل بتفاصيل ذلك، كما هو واضح في المخطط: | ||
[[ملف:Hide-Delegate-After.png|بديل=مخطط يوضح كيف يتعامل صنف العميل مع صنفٍ واحدٍ فقط وهو الصنف Person، والذي بدوره يستدعي كائنًا من صنفٍ آخر باسم Department.|بدون|مخطط يوضح كيف يتعامل صنف العميل مع صنفٍ واحدٍ فقط وهو الصنف | [[ملف:Hide-Delegate-After.png|بديل=مخطط يوضح كيف يتعامل صنف العميل مع صنفٍ واحدٍ فقط وهو الصنف Person، والذي بدوره يستدعي كائنًا من صنفٍ آخر باسم Department.|بدون|مخطط يوضح كيف يتعامل صنف العميل مع صنفٍ واحدٍ فقط وهو الصنف <code>Person</code>، والذي بدوره يستدعي كائنًا من صنفٍ آخر باسم <code>Department</code>.|تصغير|304x304px]] | ||
== لم إعادة التصميم؟ == | == لم إعادة التصميم؟ == | ||
سطر 26: | سطر 26: | ||
== مساوئ تطبيق الحل == | == مساوئ تطبيق الحل == | ||
سيؤدّي إنشاءُ عددٍ هائلٍ من توابع الانتقال ما بين الأصناف (توابع التفويض [delegation methods]) إلى الحاجة للكثير من الوسطاء (Middle Man)، وهذا بحدّ ذاته مشكلة من مشاكل الشيفرات! | سيؤدّي إنشاءُ عددٍ هائلٍ من توابع الانتقال ما بين الأصناف (توابع التفويض [delegation methods]) إلى الحاجة للكثير من [[Refactoring/middle man|الوسطاء]] (Middle Man)، وهذا بحدّ ذاته مشكلة من مشاكل الشيفرات! | ||
== آلية الحل == | == آلية الحل == | ||
سطر 40: | سطر 40: | ||
* [https://refactoring.guru/hide-delegate صفحة توثيق إخفاء التفويض في موقع refactoring.guru.] | * [https://refactoring.guru/hide-delegate صفحة توثيق إخفاء التفويض في موقع refactoring.guru.] | ||
[[تصنيف:Refactoring]] | [[تصنيف:Refactoring]] | ||
[[تصنيف:Refactoring Techniques]] | |||
[[تصنيف:Refactoring Moving Features between Objects]] |
المراجعة الحالية بتاريخ 09:10، 2 مارس 2019
المشكلة
يصل العميل (client) إلى كائنٍ (object) ما وليكن الكائن B من أحد حقول (fields) أو توابع (methods) كائنٍ آخر وليكن A، ومن ثمّ يستدعي تابعًا لهذا الكائن B.
الحل
إنشاء تابعٍ جديدٍ في الصنف A والذي يُفضي إلى استدعاءٍ للكائن B، وبهذا لن يعلم العميل تفاصيل التفويض (delegation) للكائن B ولن يعتمد على ذلك.
مثال
قبل إعادة التصميم
يتعامل صنف العميل (client class) مع صنفين، الأول صنف الأقسام (Department) والثاني صنف الأشخاص (Person) واللذان يحتويان تابعين للحصول على كائنٍ (object) من الصنف الآخر (وهما التابعان getManager
و getDepartment
)، كما في المخطط الآتي:
بعد إعادة التصميم
أصبح تعامل صنف العميل مع صنفٍ واحدٍ فقط (وهو الصنف Person
) والذي بدوره سينتقل (delegate) إلى الصنف الآخر Department
دون إرباك العميل بتفاصيل ذلك، كما هو واضح في المخطط:
لم إعادة التصميم؟
يجب أولًا الإلمام ببعض المصطلحات:
- الخادم (server): وهو الكائن (object) الذي يكون على تواصلٍ مباشرٍ مع العميل (client).
- المفوض (delegate): وهو الكائن النهائي الذي يحتوي المهام الفعلية التي يطلبها العميل.
وقد تحدث سلسلةٌ من الاستدعاءات (call chain) عندما يطلب العميل كائنًا عبر كائنٍ آخر والذي بدوره سيطلب كائنًا ثالثًا وهكذا، وهذا سيلقي بالعميل بمتاهةٍ من الأصناف والاستدعاءات، أضف لذلك أن أيّ تغييرٍ في بنية العلاقات ما بين تلك الأصناف لا بُدَّ وأن يتبعه تغيير لدى طرف العميل.
فوائد تطبيق الحل
إخفاء التفويض (الانتقال من صنف إلى آخر) عن العميل؛ إذ سيكون من الأسهل إجراء التغييرات على البرنامج إن كانت شيفرة العميل بمعزلٍ عن تفاصيل العلاقات القائمة ما بين الكائنات (objects).
مساوئ تطبيق الحل
سيؤدّي إنشاءُ عددٍ هائلٍ من توابع الانتقال ما بين الأصناف (توابع التفويض [delegation methods]) إلى الحاجة للكثير من الوسطاء (Middle Man)، وهذا بحدّ ذاته مشكلة من مشاكل الشيفرات!
آلية الحل
- إنشاء تابعٍ (method) في صنف الخادم (server class) لكلِّ تابعٍ يستدعيه العميل في صنف الوكيل (delegate class)، وذلك ليصبح استدعاء صنف الوكيل عبر التوابع الجديدة المُنشَأة في صنف الخادم.
- تعديل شيفرة العميل (client) لتستدعي توابع صنف الخادم بدلًا من التوابع السابقة.
- إن كانت تلك التغييرات تغني العميل عن صنف الوكيل، فحينئذٍ من السهل إزالة التوابع الموصلة إلى صنف الوكيل من صنف الخادم (وهي التوابع التي كانت مستخدمةً بالأصل للوصول إلى صنف الوكيل).