الفرق بين المراجعتين ل"Refactoring/replace type code with class"
جميل-بيلوني (نقاش | مساهمات) ط (مراجعة وتدقيق.) |
جميل-بيلوني (نقاش | مساهمات) (مراجعة وتدقيق.) |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: تبديل رموز الأنواع بالأصناف (Replace Type Code with Class)}}</noinclude> | <noinclude>{{DISPLAYTITLE: تبديل رموز الأنواع بالأصناف (Replace Type Code with Class)}}</noinclude> | ||
− | ما هو رمز | + | ما هو رمز النوع (type code)؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. غالبا ما تُعطى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. |
== المشكلة == | == المشكلة == | ||
− | يحتوي الصنف على حقل يحتوي على رموز الأنواع. ولا تُستخدم قيم هذا النوع في شروط المُشغِّل ولا تؤثر | + | يحتوي الصنف على حقل يحتوي على رموز الأنواع. ولا تُستخدم قيم هذا النوع في شروط المُشغِّل ولا تؤثر على سلوك البرنامج. |
[[ملف:Replace Type Code with Class - Before.png|بدون|تصغير|206x206بك]] | [[ملف:Replace Type Code with Class - Before.png|بدون|تصغير|206x206بك]] | ||
سطر 11: | سطر 11: | ||
== لم إعادة التصميم؟ == | == لم إعادة التصميم؟ == | ||
− | أحد الأسباب الأكثر شيوعًا لاستخدام رموز الأنواع هو التعامل مع قواعد | + | أحد الأسباب الأكثر شيوعًا لاستخدام رموز الأنواع هو التعامل مع قواعد البيانات؛ فعندما تحتوي قاعدة البيانات على حقول، يُجرَى فيها ترميز بعض المفاهيم المعقدة برقم أو سلسلة. |
− | + | على سبيل المثال، الصنف <code>User</code> مع الحقل <code>user_role</code>، الذي يحتوي على معلومات حول امتيازات الوصول لكل مستخدم، سواء كان المسؤول أو المحرر أو المستخدم العادي. لذلك، ففي هذه الحالة، تُرمَّز هذه المعلومات في الحقل بالحروف <code>A</code> و <code>E</code> و <code>U</code> على التوالي. | |
− | ولكن ماذا عن أوجه القصور في هذا النهج؟ لا تتحقق ضوابط (setters) الحقول غالبًا من القيمة | + | ولكن ماذا عن أوجه القصور في هذا النهج؟ لا تتحقق ضوابط (setters) الحقول غالبًا من القيمة المُرسلة التي يمكن أن تسبب مشاكل كبيرة عندما يرسل شخصٌ ما قيمًا غير مقصودة أو خاطئة إلى هذه الحقول. |
− | وبالإضافة إلى ذلك، من المستحيل التحقق من نوع هذه الحقول. فمن الممكن إرسال أي رقم أو سلسلة إليها، والتي لن | + | وبالإضافة إلى ذلك، من المستحيل التحقق من نوع هذه الحقول. فمن الممكن إرسال أي رقم أو سلسلة إليها، والتي لن يُتحقَّق من نوعها بواسطة IDE الخاص بك بل سيسمح بتشغيل البرنامج (ثم تَعطُّلُه في وقتٍ لاحق). |
== فوائد تطبيق الحل == | == فوائد تطبيق الحل == | ||
− | * المُراد تحويل مجموعات بسيطة القيم – مثل الأنواع المُرمَّزة – إلى أصناف كاملة الأهلية مع كل الفوائد التي تتيحها برمجة الكائنات. | + | * المُراد هو تحويل مجموعات بسيطة القيم – مثل الأنواع المُرمَّزة – إلى أصناف كاملة الأهلية مع كل الفوائد التي تتيحها برمجة الكائنات. |
− | * يسمح بالتلميح بنوع القيم المُمررة إلى التوابع والحقول | + | * يسمح بالتلميح بنوع القيم المُمررة إلى التوابع والحقول على مستوى لغة البرمجة وذلك باستبدال رموز الأنواع بالأصناف. |
− | + | فعلى سبيل المثال، بينما لم يكن المصرف (compiler) يُميِّز مسبقًا بين الثوابت الرقمية والأرقام العشوائية عند تمرير قيمة ما إلى التابع، أصبح الآن يُصدر تحذيرًا عن الخطأ داخل IDE الخاص بك عند تمرير البيانات التي لا تناسب صنف النوع المشار إليه. | |
− | * | + | * وبالتالي، فمن الممكن نقل الرمز إلى أصناف النوع. وإذا كانت هناك حاجة لأداء معالَجات مُعقدة باستخدام قيم الأنواع في البرنامج بأكمله، يمكن لهذا الرمز الآن "العيش" داخل أصناف النوع الواحد أو متعدد الأنواع. |
− | == متى | + | == متى يترك هذا الحل؟ == |
− | إذا استُخدِمت قيم أنواع مُرمَّزة داخل | + | إذا استُخدِمت قيم أنواع مُرمَّزة داخل بنى التحكم بالتدفق (مثل if و switch، الخ) والتحكم في سلوك الصنف، فيجب استخدام إحدى تقنيتي إعادة تصميم رمز النوع: |
* [[Refactoring/replace type code with subclasses|تبديل رموز الأنواع بالأصناف الفرعية]]. | * [[Refactoring/replace type code with subclasses|تبديل رموز الأنواع بالأصناف الفرعية]]. | ||
* [[Refactoring/replace type code with state strategy|تبديل رموز الأنواع بالحالة/الاستراتيجية]]. | * [[Refactoring/replace type code with state strategy|تبديل رموز الأنواع بالحالة/الاستراتيجية]]. | ||
== آلية الحل == | == آلية الحل == | ||
− | # أنشئ | + | # أنشئ صنفًا جديدًا وأعطه اسمًا جديدًا يتوافق مع الغرض من ترميز النوع. سنسميه هنا "صنف النوع". |
− | # انسخ الحقل الذي يحتوي على رمز النوع إلى "صنف النوع" واجعله خاصًا. ثم أنشئ | + | # انسخ الحقل الذي يحتوي على رمز النوع إلى "صنف النوع" واجعله خاصًا. ثم أنشئ مُتلقيًا (getter) للحقل. سيُعين المُنشئُ فقط قيمةً لهذا الحقل. |
− | # أنشئ | + | # أنشئ تابعًا ثابتًا في "صنف النوع" لكل قيمة لرمز النوع. سيُنشأ كائن "صنف النوع" جديد مقابل قيمة لرمز النوع هذه. |
− | # في الصنف الأصلي، استبدال نوع الحقل المُرمَّز بصنف النوع. أنشئ | + | # في الصنف الأصلي، استبدال نوع الحقل المُرمَّز بصنف النوع. أنشئ كائنًا جديدًا من هذا النوع في المُنشِئ وكذلك في ضابط الحقل. غَيِّر مُتلقي الحقل بحيث يستدعي مُتلقي "صنف النوع". |
− | # استبدِل أي | + | # استبدِل أي ذكرٍ لقيم النوع المُرمَّز باستدعاء للتوابع الخاصة بصنف النوع الساكنة. |
# أزل ثوابت النوع المُرمَّز من الصنف الأصلي. | # أزل ثوابت النوع المُرمَّز من الصنف الأصلي. | ||
سطر 44: | سطر 44: | ||
== مصادر == | == مصادر == | ||
− | * [https://refactoring.guru/replace-type-code-with-class صفحة توثيق تبديل رموز الأنواع بالأصناف في موقع refactoring.guru]. | + | * [https://refactoring.guru/replace-type-code-with-class صفحة توثيق تبديل رموز الأنواع بالأصناف في موقع refactoring.guru]. [[تصنيف:Refactoring]] [[تصنيف:Refactoring Techniques]] [[تصنيف:Refactoring Organizing Data]] |
مراجعة 13:41، 18 ديسمبر 2018
ما هو رمز النوع (type code)؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. غالبا ما تُعطى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير.
المشكلة
يحتوي الصنف على حقل يحتوي على رموز الأنواع. ولا تُستخدم قيم هذا النوع في شروط المُشغِّل ولا تؤثر على سلوك البرنامج.
الحل
إنشاء صنف جديد واستخدام كائناته بدلًا من قيم رموز الأنواع.
لم إعادة التصميم؟
أحد الأسباب الأكثر شيوعًا لاستخدام رموز الأنواع هو التعامل مع قواعد البيانات؛ فعندما تحتوي قاعدة البيانات على حقول، يُجرَى فيها ترميز بعض المفاهيم المعقدة برقم أو سلسلة.
على سبيل المثال، الصنف User
مع الحقل user_role
، الذي يحتوي على معلومات حول امتيازات الوصول لكل مستخدم، سواء كان المسؤول أو المحرر أو المستخدم العادي. لذلك، ففي هذه الحالة، تُرمَّز هذه المعلومات في الحقل بالحروف A
و E
و U
على التوالي.
ولكن ماذا عن أوجه القصور في هذا النهج؟ لا تتحقق ضوابط (setters) الحقول غالبًا من القيمة المُرسلة التي يمكن أن تسبب مشاكل كبيرة عندما يرسل شخصٌ ما قيمًا غير مقصودة أو خاطئة إلى هذه الحقول.
وبالإضافة إلى ذلك، من المستحيل التحقق من نوع هذه الحقول. فمن الممكن إرسال أي رقم أو سلسلة إليها، والتي لن يُتحقَّق من نوعها بواسطة IDE الخاص بك بل سيسمح بتشغيل البرنامج (ثم تَعطُّلُه في وقتٍ لاحق).
فوائد تطبيق الحل
- المُراد هو تحويل مجموعات بسيطة القيم – مثل الأنواع المُرمَّزة – إلى أصناف كاملة الأهلية مع كل الفوائد التي تتيحها برمجة الكائنات.
- يسمح بالتلميح بنوع القيم المُمررة إلى التوابع والحقول على مستوى لغة البرمجة وذلك باستبدال رموز الأنواع بالأصناف.
فعلى سبيل المثال، بينما لم يكن المصرف (compiler) يُميِّز مسبقًا بين الثوابت الرقمية والأرقام العشوائية عند تمرير قيمة ما إلى التابع، أصبح الآن يُصدر تحذيرًا عن الخطأ داخل IDE الخاص بك عند تمرير البيانات التي لا تناسب صنف النوع المشار إليه.
- وبالتالي، فمن الممكن نقل الرمز إلى أصناف النوع. وإذا كانت هناك حاجة لأداء معالَجات مُعقدة باستخدام قيم الأنواع في البرنامج بأكمله، يمكن لهذا الرمز الآن "العيش" داخل أصناف النوع الواحد أو متعدد الأنواع.
متى يترك هذا الحل؟
إذا استُخدِمت قيم أنواع مُرمَّزة داخل بنى التحكم بالتدفق (مثل if و switch، الخ) والتحكم في سلوك الصنف، فيجب استخدام إحدى تقنيتي إعادة تصميم رمز النوع:
آلية الحل
- أنشئ صنفًا جديدًا وأعطه اسمًا جديدًا يتوافق مع الغرض من ترميز النوع. سنسميه هنا "صنف النوع".
- انسخ الحقل الذي يحتوي على رمز النوع إلى "صنف النوع" واجعله خاصًا. ثم أنشئ مُتلقيًا (getter) للحقل. سيُعين المُنشئُ فقط قيمةً لهذا الحقل.
- أنشئ تابعًا ثابتًا في "صنف النوع" لكل قيمة لرمز النوع. سيُنشأ كائن "صنف النوع" جديد مقابل قيمة لرمز النوع هذه.
- في الصنف الأصلي، استبدال نوع الحقل المُرمَّز بصنف النوع. أنشئ كائنًا جديدًا من هذا النوع في المُنشِئ وكذلك في ضابط الحقل. غَيِّر مُتلقي الحقل بحيث يستدعي مُتلقي "صنف النوع".
- استبدِل أي ذكرٍ لقيم النوع المُرمَّز باستدعاء للتوابع الخاصة بصنف النوع الساكنة.
- أزل ثوابت النوع المُرمَّز من الصنف الأصلي.
انظر أيضًا
- تبديل رموز الأنواع بالأصناف الفرعية.
- تبديل رموز الأنواع بالحالة/الاستراتيجية.
- هوس الحقول الأساسية (Primitive Obsession).