استخراج الأصناف الفرعية (Extract Subclass)
المشكلة
يكون للصنف ميزات تستعمل فقط في حالات معينة.
الحل
إنشاء صنف فرعي واستخدامه في هذه الحالات.
مثال
قبل إعادة التصميم
يراد استعمال الصنف Job
- بالإضافة إلى استعماله الطبيعي أيضًا - في حالات مخصصة فقط:
بعد إعادة التصميم
إنشاء الصنف الفرعي Labor
الذي سيخصص لحالات الاستعمال النادرة تلك من الصنف Job
:
لم إعادة التصميم؟
يحتوي الصنف الرئيسي على توابع وحقول لتطبيق حالة نادرة معينة لاستخدام الصنف. وفي حين أن الحالة نادرة الحدوث، يكون الصنف مسؤولًا عنها وسيكون من الخطأ نقل جميع الحقول والتوابع المرتبطة بها إلى صنفٍ منفصلٍ تمامًا. لكن يمكن نقلهم إلى صنف فرعي، وهو ما سنفعله بمساعدة تقنية إعادة التصميم هذه.
فوائد تطبيق الحل
- إنشاء صنف فرعي بسرعة وسهولة.
- إمكانية إنشاء عدة أصناف فرعية منفصلة إذا كان الصنف الرئيسي ينجز حاليًا أكثر من مثل هذه الحالة الخاصة.
مساوئ تطبيق الحل
- على الرغم من ما يبدو عليه من بساطة، يمكن أن يؤدي التوريث إلى طريق مسدود إذا كان عليك فصل عدة تسلسلات هرمية مختلفة للصنف. إذا وُجِد على سبيل المثال الصنف
Dogs
وله سلوكًا مختلفًا اعتمادًا على حجم وفراء الكلاب، يمكن استنباط اثنين من التسلسلات الهرمية:- بحسب الحجم:
Large
وMedium
وSmall
- بحسب الفراء:
Smooth
وShaggy
- بحسب الحجم:
كل شيء سيكون على ما يرام، إلا أن المشاكل سوف تتفاقم حالما تحتاج إلى إنشاء صنف كلب يكون Large
و Smooth
على حد سواء، إذ يمكنك إنشاء كائن من صنفٍ واحدٍ فقط. ومع ذلك، يمكنك تجنب هذه المشكلة باستخدام التركيب بدلًا من الميراث (انظر نمط الاستراتيجية). وبعبارة أخرى، سيكون للصنف Dog
حقلين مكونين، الحجم والفراء. ستقوم بتركيب العناصر المكونة من الأصناف اللازمة إلى هذه الحقول. حتى تتمكن من إنشاء كلب Dog
لديه حجم كبير LargeSize
وفراء أشعث ShaggyFur
.
آلية الحل
- أنشئ صنفًا فرعيًّا جديدًا من الصنف المعني.
- إذا كنت بحاجة إلى بيانات إضافية لإنشاء كائنات من صنفٍ فرعي، أنشئ بانيًّا وأضف المعاملات اللازمة إليه. لا تنسَ استدعاء تطبيق أصل الباني.
- ابحث عن كل استدعاءات باني الصنف الأصل. عندما تكون وظيفة الصنف الفرعي ضرورية، يستعاض عن الباني الأصل بالباني الفرعي.
- انقل التوابع والحقول الضرورية من الصنف الأصل إلى الصنف الفرعي. قم بهذا من خلال دفع التابع لأسفل ودفع الحقل لأسفل. من الأسهل البدء بنقل التوابع أولًا. وبهذه الطريقة، تظل الحقول متاحة طوال العملية بأكملها: من الصنف الأصل قبيل الانتقال، ومن الصنف الفرعي نفسه بعد اكتمال النقل.
- بعد أن يكون الصنف الفرعي جاهزًا، ابحث عن كل الحقول القديمة التي تحكمت في اختيار الوظيفة. احذف هذه الحقول باستخدام التعدديّة الشكليّة لتحل محل جميع العوامل التي استخدمت فيها الحقول. مثال بسيط: في صنف السيارات، يوجد الحقل
isElectricCar
، واعتمادًا عليه، في التابع()refuel
، تكون السيارة إما مزودة بالمحروقات أو مشحونة بالكهرباء. بعد إعادة التصميم، يحذف الحقلisElectricCar
وسيكون للصنفينCar
وElectricCar
التطبيقات الخاصة بهما في تابع()refuel
.