نتائج البحث

اذهب إلى التنقل اذهب إلى البحث

مشكلات أخرى (Other Smells)

ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد وهي: أصناف المكتبة غير الكافية (Incomplete Library Classes) المشكلة: لا تلبِّي أصناف المكتبة كافّة احتياجات البرنامج مع استمرار تطوُّره، ولا يمكن تعديلها لأنّها مُخصَّصةٌ للقراءة فقط. الحل: تعريف التوابع الدخيلة، أو تعريف الإضافات المحليّة. انظر أيضًا المبالغة والإطالة الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه عرقلة التغيير الأجزاء الفائضة  الروابط الازدواجية مصادر [1]صفحة توثيق مشكلات أخرى في موقع refactoring.guru.

اختلال الشيفرات ومشاكلها (Code Smells)

قد تعاني الشيفرات الكثير من الاختلالات والمشاكل الشكلية؛ فبمجرد اكتشاف تلك الاختلالات الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه الاختلالات: المبالغة والإطالة قد يزداد حجم الشيفرات والتوابع (methods) والأصناف (classes) ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ولا يحدث هذا بشكلٍ فجائيِّ دفعةً واحدةً، بل يكون ناتجًا عن تراكم الإضافات أثناء تطوير البرنامج (وخاصةً عندما لا يبذل أحدٌ جهدًا للحدِّ من ذلك التشعب)، ويبدو هذا التضخم واضحًا التوابع الطويلة (long methods): ...

خطوات إعادة التصميم (Refactoring)

تجري عملية إعادة التصميم (refactoring) عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية: الحصول على شيفرةٍ نظيفة (clean code) إن لم تصبح الشيفرة أنظف من بعد إعادة التصميم فهذا هدرٌ للوقت، ولكن ما السبب؟ يحدث كثيرًا أن تحيد عن سياق إعادة التصميم بتغييراتٍ تدريجيّة صغيرةٍ لتتجه نحو إجراء تغييرٍ كبيرٍ واحدٍ! وهذا خطأ ومن السهل الوقوع ...

تقنيات إعادة التصميم (Refactoring Techniques)

إنشاء التوابع تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية. يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة، وهذه التقنيات هي: استخراج التوابع (Extract Methods): والتي تتمثل بوجود أجزاء من الشيفرة يُمكن عزلها وتجميعها سويةً. دمج التوابع (Inline ...

الأصناف الخاملة (Lazy Classes)

توصيف المشكلة وجود بعض الأصناف (classes) قليلة الاستخدام ولا أهمية لها في البرنامج، ويجدر التخلُّص منها إذ إنّ فهم وصيانة الأصناف يكلِّفان الوقت والجهد. أسبابها يكون تصميم الصنف بدايةً لأداء مهامٍ (functionality) معيّنة، ولكنّه قد يصبح صغيرًا لا أهميّة له من بعد الكثير من عمليات إعادة التصميم (refactoring). قد تُخصَّص بعض الأصناف لدعم التطوير المستقبلي للبرنامج (كالتخطيط المُسبق لميّزاتٍ ستُضاف لاحقًا)، وتصبح تلك الأصناف خاملةً عندما لا يحدث أيُّ تطويرٍ فيما بعد. وما الحل؟ تضمين الأصناف (inline classes) للعناصر (components) ...

متى تحتاج إعادة التصميم؟ (When to Refactor)

نحتاج إلى إعادة التصميم (قاعدة المرات الثلاث): عند قيامك بأيّة مهمةٍ للمرّة الأولى، فالمهم هو إنجازها والحصول على النتيجة وحسب. لدى قيامك بمهمةٍ مشابهةٍ للمرّة الثانية قد ترفض بادئ الأمر فكرة التكرار ولكنك ستجد نفسك تقوم بنفس العمل! عند قيامك بالمهمة للمرّة الثالثة، ستحتاج إعادة التصميم. عند إضافة ميّزةٍ (feature) جديدة تساعد عملية إعادة التصميم (refactoring) على فهم شيفرات المبرمجين الآخرين بشكلٍ أفضل، وعند العمل على الشيفرة غير الجيدة لأحدهم فعليك بإعادة تصميمها أولًا، وهذا ضروريٌّ إذ يصبح التحكُّم بالشيفرة ...

الأصناف الواسعة (Large Classes)

توصيف المشكلة احتواء الصنف (class) العديدَ من الحقول (fields) والتوابع (methods) وشيفرةً بأسطرَ كثيرةٍ. أسبابها تبدأ الأصناف صغيرةً ليزداد حجمها مع استمرار تطوُّر البرنامج (كما الحال بالتوابع الطويلة) لأنَّ المبرمج يرى أنَّ إضافة ميِّزاتٍ (features) جديدةٍ في صنفٍ موجودٍ مسبقًا أكثر سهولةً من إنشاء أصنافٍ جديدةٍ مخصَّصةٍ لها. وما الحل؟ الحل بسيطٌ جدًا؛ وهو تقسيم الصنف، وذلك بإحدى الوسائل الآتية: إنشاء صنفٍ جديدٍ (Extract Class) إن كان من الممكن فصلُ بعض مهامّ الصنف الحاليّ ونقلها للصنف الجديد. إنشاء صنفٍ فرعيٍّ ...

الشيفرة النظيفة (Clean Code)

تهدف عملية إعادة التصميم (refactoring) للتخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ مُبسَّط، وهذا -لا بُدَّ- أمرٌ رائعٌ ولكن بالبداية؛ ما معنى أن تكون الشيفرة نظيفةً؟ مميزات الشيفرة النظيفة فيما يأتي بعضٌ مما يميز الشيفرة النظيفة: واضحةٌ ومقروءةٌ للمبرمجين الآخرين إنّ ما يجعل الشيفرات أكثر تعقيدًا (بعيدَا عن الخوارزميّات فائقة التعقيد) هو اعتمادها على تسمية المتغيِّرات تسميةً ضعيفةً (غير منطقيّةٍ أو بدون معنى) أو احتوائها على أصناف (classes) ...

الأعباء التقنية (Technical Debt)

يبذل المبرمج عادةً ما بوسعه لكتابة شيفرةٍ جيدةٍ، ولا ينوي أبدًا -أيًّا كان المبرمج- الحصولَ على شيفرةٍ رديئةٍ تكون السبب في فشل مشروعه البرمجيّ، لذا فلنطرح السؤال: ما هو الحدُّ الذي تصبح عنده الشيفرةُ النظيفةُ رديئةً؟ فخ الأعباء التقنية اقتُرح مصطلح "الأعباء أو الالتزامات التقنيّة" (ويقابله بالانكليزيّة Technical Debt) للمرّة الأولى من قِبل Ward Cunningham، فإنه لدى اقتراضك مبلغًا ماليًا من أحد المصارف تكبُر أمامك فرصة الشراء بشكلٍ أسرع، ويحدث أن تدفعَ علاوةً (وأيّ إضافات أخرى) لتسريع الأمر والحصول على ...

نقل الميزات ما بين الكائنات (Moving Features between Objects)

تساعد عملية إعادة التصميم (refactoring) في توزيع المهام بشكل مثاليّ على الأصناف (classes) المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام (functionality) ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ (implementation) من الوصول العام (public access)، وهذه التقنيات تشمل: نقل التابع (Move Method) المشكلة: استخدام التابع (method) في صنفٍ (class) ما أكثر من استخدامه في صنفه الأساسيّ. الحل: إنشاء تابعٍ جديدٍ في الصنف الأكثر استخدامًا لذلك التابع ونقل شيفرته إلى التابع الجديد، ثم تحويل الشيفرة ...

نقل الميزات ما بين الكائنات (Moving Features between Objects)

تساعد عملية إعادة التصميم (refactoring) في توزيع المهام بشكل مثاليّ على الأصناف (classes) المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام (functionality) ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ (implementation) من الوصول العام (public access)، وهذه التقنيات تشمل: نقل التابع (Move Method) المشكلة: استخدام التابع (method) في صنفٍ (class) ما أكثر من استخدامه في صنفه الأساسيّ. الحل: إنشاء تابعٍ جديدٍ في الصنف الأكثر استخدامًا لذلك التابع ونقل شيفرته إلى التابع الجديد، ثم تحويل الشيفرة ...

تبديل قيم البيانات إلى كائنات (Replace Data Values with Objects)

المشكلة وجود حقلٍ (field) مٌخصَّص للبيانات في صنفٍ (class) ما (أو في عددٍ من الأصناف)، ولهذا الحقل بياناته وسلوكه (behaviour) المرتبط به. الحل إنشاء صنفٍ جديدٍ ليُوضَع فيه الحقل (field) بالإضافة إلى سلوكه المرتبط به، وتخزين كائنٍ (object) من هذا الصنف الجديد في الصنف الأصليّ للحقل. مثال قبل إعادة التصميم يحتوي الصنف Order على الحقل customer الذي يحتوي بيانات نصيّة (من النوع String) كما هو واضح في مخطط الأصناف الآتي: الصنف Order يحتوي على الحقل customer الذي يحتوي بيانات نصيّة. ...

هوس الحقول الأساسية (Primitive Obsession)

توصيف المشكلة تظهر المشكلة بعدَّة جوانب: استخدام الحقول الأساسيّة (primitives) بدلًا من الكائنات (objects) لأداء المهامّ البسيطة (مثل: عمليات العملة [currency] والمجالات [ranges] والسلاسل النصية [strings] المُخصَّصة للأرقام الهاتفية، …إلخ.). استخدام الثوابت (constants) لترميز المعلومات (مثل استخدام الثابت USER_ADMIN_ROLE = 1 للدلالة على المستخدمين ذوي الصلاحيّات الإداريّة). استخدام الثوابت النصيّة (string constants) كأسماءٍ للحقول (fields) في مصفوفات البيانات (data arrays). أسبابها تنشأ هذه المشكلة بسبب العبارة المُدمِّرة التي يفكّر بها المبرمجون بلحظة ضعفٍ: "حقلٌ واحدٌ فقط، ولتخزين معلومةٍ بسيطةٍ وحسب!"ولأنهم ...

التعليقات (Comments)

توصيف المشكلة وجود الكثير من التعليقات في التوابع (methods) بهدف الشرح التفصيليّ للشيفرة. أسبابها غالبًا ما يكون السبب منطقيًّا لإضافة التعليقات وخاصّة عندما تكون الشيفرة مبهمةً غير واضحة، لكن بهذه الحالة لن نعدَّ تلك التعليقات إلا محاولاتٍ بائسةً لتغطية الشيفرة الرديئة بجانبها! ولتكن القاعدة: إنّ أفضل تعليقٍ يمكن أن تضيفه هو تسمية التوابع (methods) والأصناف (classes) تسميةً جيّدةً معبِّرة. وإذا ما وجدتَ أن الشيفرة لن تكون واضحةً بحذف التعليقات المُضافة، فمن المُؤسف القول بضرورة تغيير بُنيتها (structure) إلى الشكل الذي ...

سلاسل الرسائل (Message Chains)

توصيف المشكلة وجود العديد من الاستدعاءات المتسلسلة في الشيفرة، مثل: ‎$a->b()->c()->d()‎. أسبابها تحدث المشكلة عند طلب العميل (client request) كائنًا (object) آخر والذي بدوره يطلب كائنًا آخر ثالثًا وهكذا، مما يعني اعتماد العميل على التنقّل (navigation) في بنية الأصناف (class structure)، وبالتالي فإنّ أيّ تعديلٍ في تلك العلاقات سيتطلَّبُ إجراء التعديلات أيضًا على العميل بحدِّ ذاته. وما الحل؟ إخفاء التفويض (hide delegate) لحذف الاستدعاءات المُتسلسلة. قد يساعد -ببعض الحالات- التفكيرُ بسبب الوصول إلى آخر كائنٍ (object) مستدعى، وعندها يمكن اللجوء ...

الوراثة الفائضة (Refused Bequest)

توصيف المشكلة استفادة الصنف الفرعيّ (subclass) من القليل فقط ممّا ورِثه عن الصنف الأعلى (superclass) من توابعَ (method) وحقولٍ (fields)، لتبقى التوابع الأخرى غيرَ مُستخدَمةٍ أو قد يُعاد تعريفها (redefined) مع الكثير من الاختلافات. أسبابها إنشاء علاقة الوراثة (inheritance) ما بين صنفين مختلفين كليًّا بدافع إعادة استخدام الشيفرة الموجودة في الصنف الأعلى (superclass) في الصنف الفرعيّ (subclass). وما الحل؟ إن لم يشترك الصنف الفرعيّ (subclass) مع الصنف الأعلى (superclass) بشيءٍ، فالوراثة غير منطقيّةٍ بالأصل، والأفضلُ التخلي عنها بتبديلها إلى تفويض ...

الأجزاء الفائضة (Dispensables)

وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة، منها: التعليقات (comments) المشكلة: وجود الكثير من التعليقات في التوابع (methods) بهدف الشرح التفصيليّ للشيفرة. الحل: يكون الحل بناءً على الحالة المستعملة وهو: تقسيم التعبير الواحد إلى تعابيرَ فرعيّة (subexpressions) بالاعتماد على استخراج المتغيِّرات، أو عزل ذلك المقطع في تابعٍ (method) جديدٍ باسمٍ معبِّر، أو إعادة تسمية التابع (rename method) لاسمٍ يشرح ذاته بذاته، أو إضافة التأكيدات. تكرار  الشيفرة (duplicates) المشكلة: التشابه (أو التطابق المطلق) بين مقطعين من الشيفرة ...

الهيكلية التفرعية للوراثة (Parallel Inheritance Hierarchies)

توصيف المشكلة يتطلَّب إنشاءُ صنفٍ فرعيٍّ (subclass) لأحد الأصناف إنشاءَ صنفٍ فرعيٍّ ثانٍ لصنفٍ آخر غيره. أسبابها لا تبدو المشكلة واضحةً في الهيكليّات (hierarchies) الصغيرة، ولكنها تبدأ بالظهور مع إضافة أصناف (classes) جديدةٍ ممّا يجعل إجراء التعديلات أمرًا صعبًا. وما الحل؟ التخلُّص من التكرار التفرعيّ بين الهيكليّتين (hierarchies)، ويتمّ بخطوتين: إنشاء مرجعيّة (reference) من إحدى الهيكليّتين التفرعيّتين إلى الهيكليّة الثانية. إزالة الهيكليّة في الصنف المُشار إليه (referred class)، وذلك بنقل التوابع (move methods) ونقل الحقول (move fields). إليك المزيد ستحصل ...

أصناف البيانات (Data Classes)

توصيف المشكلة وجود العديد من أصناف البيانات في الشيفرة، والتي تُستخدَم لتخزين البيانات التي تحتاج إليها الأصناف الأخرى، إذ تحتوي على حقولٍ للبيانات (fields) وتوابع للوصول إليها (accessors) أي توابعَ للحصول على بيانات الحقول (getter) وأخرى لتعديلها (setter)، ولا تقوم هذه الأصناف بأيّ مهمّة أخرى ولا تستطيع كذلك تنفيذ العمليات (operations) على بياناتها بمفردها. أسبابها من الطبيعي أن يحتوي الصنف -بادئ الأمر- على القليل من الحقول العامّة (public fields) وبعض التوابع للوصول إليها (accessors) ولكن إن استمرَّ الصنف كذلك فلن ...

الأصناف البديلة (alternative) ذات الواجهات (interfaces) المختلفة

توصيف المشكلة التطابق بالمهام (function) ما بين صنفين (classes) ولكن بأسماءٍ مختلفةٍ لتوابعهما (methods). أسبابها عدم دراية المبرمج بوجود صنفٍ آخر يكافِئ بمهامّه مهامّ الصنف الحالي الذي ينشِئه. وما الحل؟ حذف أحد الصنفين بعد تنفيذ إحدى الحلول الآتية: إعادة تسمية التوابع (methods) لتصبح متطابقةً بكافّة الأصناف البديلة (alternative) (أي الأصناف المتكافئة بالمهام). توحيد التوقيع (signature) وتعريف الاستخدام ما بين التوابع، وذلك إمّا بنقل التابع (move method) أو إضافة المعاملات (add parameters) أو دمج التوابع عبر المعاملات (parameterize method). إن كان ...

عرض (20 السابقة | 20 التالية) (20 | 50 | 100 | 250 | 500).