استبدال كود النوع بفئات فرعية.
لديك نوع مرمز يؤثر بشكل مباشر على سلوك البرنامج (تؤدي قيم هذا الحقل إلى تشغيل أكواد برمجية مختلفة في الجمل الشرطية).
أنشئ فئات فرعية لكل قيمة من قيم النوع المرمز. ثم استخلص السلوكيات ذات الصلة من الفئة الأصلية إلى هذه الفئات الفرعية. واستبدل كود تدفق التحكم بتعدد الأشكال.
##Example


##Why Refactor
تعتبر تقنية إعادة الهيكلة هذه شكلًا أكثر تعقيدًا من تقنية استبدال كود النوع بفئة.
كما هو الحال في طريقة إعادة الهيكلة الأولى، لديك مجموعة من القيم البسيطة التي تشكل جميع القيم المسموح بها لحقل ما. على الرغم من أن هذه القيم غالبًا ما يتم تحديدها كثوابت ولها أسماء مفهومة، إلا أن استخدامها يجعل الكود الخاص بك عرضة للأخطاء لأنها لا تزال قيمًا أولية في الواقع. على سبيل المثال، لديك دالة تقبل إحدى هذه القيم في المعلمات. في لحظة معينة، بدلاً من الثابت USER_TYPE_ADMIN ذي القيمة "ADMIN"، تستقبل الدالة نفس السلسلة النصية ولكن بأحرف صغيرة ("admin")، مما سيؤدي إلى تنفيذ شيء آخر لم يقصده الكاتب (أنت).
هنا نتعامل مع كود تدفق التحكم مثل الجمل الشرطية if و switch و ?:. بمعنى آخر، يتم استخدام الحقول ذات القيم المرمزة (مثل $user->type === self::USER_TYPE_ADMIN) داخل شروط هذه العوامل. إذا أردنا استخدام استبدال كود النوع بفئة هنا، فمن الأفضل نقل كل هياكل تدفق التحكم هذه إلى فئة مسؤولة عن نوع البيانات. في النهاية، سيؤدي هذا بالطبع إلى إنشاء فئة نوع مشابهة جدًا للفئة الأصلية، مع وجود نفس المشاكل أيضًا.
##Benefits
-
حذف كود تدفق التحكم (control flow code). بدلاً من استخدام عبارة
switchضخمة في الفئة الأصلية، انقل الكود إلى الفئات الفرعية المناسبة. يؤدي هذا إلى تحسين الالتزام بـ مبدأ المسؤولية الفردية (Single Responsibility Principle) ويجعل البرنامج أكثر مقروئية بشكل عام. -
إذا كنت بحاجة إلى إضافة قيمة جديدة لنوع مرمز، فكل ما عليك فعله هو إضافة فئة فرعية جديدة دون لمس الكود الحالي (راجع مبدأ الفتح/الإغلاق - Open/Closed Principle).
-
من خلال استبدال كود النوع بفئات، فإننا نمهد الطريق للتلميح بالنوع (type hinting) للدوال والحقول على مستوى لغة البرمجة. لن يكون هذا ممكنًا باستخدام قيم رقمية أو نصية بسيطة موجودة في نوع مرمز.
##How to Refactor
-
استخدم التغليف الذاتي للحقل (Self Encapsulate Field) لإنشاء دالة جلب (getter) للحقل الذي يحتوي على كود النوع.
-
اجعل باني الفئة الفائقة (superclass constructor) خاصًا (private). أنشئ دالة مصنع ثابتة (static factory method) بنفس المعلمات الخاصة بباني الفئة الفائقة. يجب أن تحتوي على المعلمة التي ستأخذ القيم الأولية للنوع المرمز. بناءً على هذه المعلمة، ستقوم دالة المصنع بإنشاء كائنات من فئات فرعية مختلفة. للقيام بذلك، يجب عليك إنشاء جملة شرطية كبيرة في الكود الخاص بها، ولكن على الأقل، ستكون هي الجملة الشرطية الوحيدة عندما يكون ذلك ضروريًا حقًا؛ وبخلاف ذلك، ستفي الفئات الفرعية وتعدد الأشكال بالغرض.
-
أنشئ فئة فرعية فريدة لكل قيمة من قيم النوع المرمز. فيها، أعد تعريف دالة جلب النوع المرمز بحيث تعيد القيمة المقابلة للنوع المرمز.
-
احذف الحقل الذي يحتوي على كود النوع من الفئة الفائقة. واجعل دالة الجلب الخاصة به مجردة (abstract).
-
الآن بعد أن أصبحت لديك فئات فرعية، يمكنك البدء في نقل الحقول والدوال من الفئة الفائقة إلى الفئات الفرعية المقابلة (بمساعدة إنزال الحقل (Push Down Field) و إنزال الدالة (Push Down Method)).
-
عندما يتم نقل كل شيء ممكن، استخدم استبدال الشرط بتعدد الأشكال (Replace Conditional with Polymorphism) للتخلص من الشروط التي تستخدم كود النوع مرة واحدة وإلى الأبد.