استبدال التوريث بالتفويض (Replace Inheritance with Delegation)

من موسوعة حسوب
< Refactoring
مراجعة 11:28، 26 فبراير 2019 بواسطة جميل-بيلوني (نقاش | مساهمات) (مراجعة وتدقيق.)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

المشكلة

يستخدم صنف فرعي جزءًا فقط من توابع صنفه الأب (أو من غير الممكن وراثة بيانات الصنف الأب).

الحل

إنشاء حقل ووضع كائن صنف أب فيه، وتفويض التوابع إلى كائن الصنف الأب، والتخلص من التوريث.

مثال

قبل إعادة التصميم

يستخدم الصنف الفرعي Stack جزءًا من توابع صنفه الأب Vector:

يستخدم صنف فرعي جزءًا فقط من توابع صنفه الفائق.
يستخدم صنف فرعي جزءًا فقط من توابع صنفه الفائق.

بعد إعادة التصميم

إنشاء الحقل vector في الصنف Stack ووضع كائن للصنف الأب Vector فيه وتفويض التابع ()isEmpty إليه والتخلص من التوريث:

إنشاء حقل ووضع كائن صنف فائق فيه، وتفويض توابع إلى كائن الصنف الفائق، والتخلص من التوريث.
إنشاء حقل ووضع كائن صنف فائق فيه، وتفويض توابع إلى كائن الصنف الفائق، والتخلص من التوريث.

لم إعادة التصميم؟

يمكن أن يحسّن استبدال التوريث بالتكوين من تصميم الصنف تحسينًا كبيرًا إذا:

  • انتهك الصنف الفرعي مبدأ ليسكوف للتعويض (Liskov substitution principle)، أي إذا كان التوريث يتحقق فقط لدمج الشيفرة المشتركة ولكن ليس لأن الصنف الفرعي هو امتداد للصنف الأب.
  • يستخدم الصنف الفرعي جزءًا فقط من توابع الصنف الأب. في هذه الحالة، تكون فقط مسألة وقت قبل أن يستدعي شخصُ ما تابعَ صنفٍ أبٍ لم يكن من المفترض استدعاءه.

في الحقيقة، تقسم تقنية إعادة التصميم هذه كلا الصنفين وتجعل الصنف الفائق مساعدًا للصنف الفرعي، وليس أصله. فبدلًا من وراثة جميع توابع الصنف الأب، لن يكون للصنف الفرعي سوى التوابع اللازمة لتفويض توابع كائن الصنف الأب.

فوائد تطبيق الحل

  • لا يحتوي الصنف على أي توابع غير مطلوبة موروثة من الصنف الأب.
  • يمكن وضع الكائنات المختلفة ذات التطبيقات المختلفة في الحقل المفوَّض. في الواقع تحصل على نمط تصميم الاستراتيجية.

مساوئ تطبيق الحل

  • يجب كتابة العديد من توابع التفويض البسيطة.

آلية الحل

  1. أنشئ حقلًا في الصنف الفرعي لحفظ الصنف الأب فيه. خلال المرحلة الأولية، ضع الكائن الحالي فيه.
  2. غيّر توابع الصنف الفرعي بحيث تستخدم كائن الصنف الأب بدلًا من الكائن this.
  3. بالنسبة للتوابع الموروثة من الصنف الأب المستدعاة في شيفرة العميل، أنشئ توابع تفويض بسيطة في الصنف الفرعي.
  4. أزل تعريف التوريث من الصنف الفرعي.
  5. غير شيفرة التهيئة للحقل الذي يخزَّن فيه الصنف الأب السابق عن طريق إنشاء كائن جديد.

انظر أيضًا

مصادر

صفحة توثيق استبدال التوريث بالتفويض في موقع refactoring.guru.