تبديل رموز الأنواع بالحالة/الاستراتيجية (Replace Type Code with State/Strategy)
ما هو رمز النوع؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. وغالبًا ما تُعطَى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير.
المشكلة
يؤثر نوع مُرمَّز على سلوك البرنامج ولكن لا يمكن استخدام الأصناف الفرعية للتخلص منه.
الحل
استبدال رمز النوع بكائن حالة. إذا كان من الضروري استبدال قيمة حقل برمز النوع، فسيكون كائن حالة آخر "موصولًا" ("plugged-in").
مثال
قبل إعادة التصميم
الصنف Employee
يحتوي على عنصرين ذوي نوع مرمز ولا يمكن استعمال الأصناف الفرعية للتخلص منهما.
بعد إعادة التصميم
إنشاء كائن الحالة EmployeeType
ليحل مكان عناصر ذات رمز نوع في الصنف Employee
.
لم إعادة التصميم؟
يؤثر رمز النوع على سلوك الصنف، لذلك لا يمكن استخدام تبديل رموز الأنواع بالأصناف.
يؤثر رمز النوع على سلوك الصنف ولكن لا يمكن إنشاء أصناف فرعية للنوع المُرمَّز بسبب التسلسل الهرمي للصنف الموجود أو لأسباب أخرى. مما يعني أنه لا يمكن أن تطبيق تبديل رموز الأنواع بالأصناف الفرعية.
فوائد تطبيق الحل
- تقنية إعادة التصميم هذه هي طريقة للخروج من الحالات التي يُغيِّر فيها حقل مع نوع مُرمَّز من قيمته طوال عمر الكائن. في هذه الحالة، تُستبدَل القيمة عن طريق استبدال كائن الحالة الذي يشير إليه الصنف الأصلي.
- إذا دعت الحاجة إلى إضافة قيمة جديدة من نوع مُرمَّز، فيجب إضافة صنف حالة فرعي جديد دون تغيير الرمز الموجود (راجع مبدأ مفتوح/مغلق).
مساوئ تطبيق الحل
إذا وجدت حالة بسيطة من رمز النوع ولكن استخدمت تقنية إعادة التصميم على أية حال، سيكون هناك الكثير من الأصناف الإضافية (غير الضرورية).
من الجيد أن نعرف
يمكن أن يستخدم تنفيذ تقنية إعادة التصميم واحدًا من نمطي التصميم التاليين: الحالة (State) أو الاستراتيجية (Strategy). ويكون التنفيذ متشابهًا بغض النظر عن استخدام أيٍّ من النمطين. لذا أي نمط يجب اختياره لكل موقف؟
إذا كنت بصدد محاولة تقسيم الشرط الذي يتحكم في تحديد الخوارزميات، فاستخدم نمط الاستراتيجية.
ولكن إذا كانت كل قيمة من النوع المُرمَّز مسؤولة ليس فقط عن تحديد الخوارزمية ولكن عن كامل شرط الصنف، وحالة الصنف، وقيم الحقل، والعديد من الإجراءات الأخرى، فسيكون استعمال نمط الحالة هو الأفضل لهذه المهمة.
آلية الحل
- استخدم التغليف الداخلي للحقل لإنشاء مُتلقي للحقل يحتوي على رمز النوع.
- أنشئ صنفًا جديدًا واعطه اسمًا ذا معنًى يتناسب مع الغرض من رمز النوع. سيلعب هذا الصنف دور الحالة (أو الاستراتيجية). أنشئ مُتلقي حقل مُرمَّز مجرد داخله.
- أنشئ أصنافًا فرعيةً لصنف الحالة لكل قيمة من النوع المُرمَّز. في كل صنف فرعي، أعد تعريف المُتلقي للحقل المُرمَّز بحيث تعيد القيمة المقابلة من النوع المُرمَّز.
- في صنف الحالة المجردة، أنشئ تابعًا منتجًا ساكنًا (static factory method) يقبل قيمة النوع المُرمَّز كمعامل. اعتمادًا على هذا المعامل، سيُنشئ التابع المنتج كائنات بحالات مختلفة. لهذا، أنشئ في رمزه شرطية كبيرة، إذ ستكون الوحيدة عند اكتمال إعادة تصميم.
- غيِّر نوع ترميز الحقل في الصنف الأصلي إلى صنف الحالة. استدعِ تابع حالة التصميم في ضابط الحقل للحصول على كائنات حالة جديدة.
- يمكن الآن البدء في نقل الحقول والتوابع من الصنف الأب إلى أصناف الحالة الفرعية المناظرة (باستخدام حقل الدفع إلى أسفل وتابع الدفع إلى أسفل).
- عند نقل كل ما يمكن نقله، استخدم تبديل الشرطيات بالتعدديّة الشكليّة من أجل التخلص من الشرطيات التي تستخدم رمز النوع مرة واحدة وإلى الأبد.
انظر أيضًا
- تبديل رموز الأنواع بالأصناف.
- تبديل رموز الأنواع بالأصناف الفرعية.
- التغليف الداخلي للحقل.
- حقل الدفع إلى أسفل.
- تابع الدفع إلى أسفل.
- تبديل الشرطيات بالتعدديّة الشكليّة.