نتائج البحث

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

تنظيم البيانات (Organizing Data)

تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال. وهذه التقنيات هي: التغليف الداخلي للحقول (Self Encapsulate Fields) المشكلة: الوصول المباشر إلى الحقول الخاصّة داخل الصنف. الحل: إنشاء تابعي الجلب (getter) والضبط (setter) للحقل الخاصّ ومنع الوصول إليه إلا عبرهما. تبديل قيم البيانات إلى كائنات (Replace Data Values with Objects) المشكلة: وجود حقلٍ ...

دفع الحقل لأسفل (Push Down Field)

المشكلة هل يستخدم الحقل في بعض الأصناف الفرعية فقط؟ الحل نقل الحقل إلى هذه الأصناف الفرعية. مثال قبل إعادة التصميم يُستخدَم الحقل fuel الموجود في الصنف Unit الأب في صنف فرعي واحد فقط الذي هو Tank: يستخدم الحقل في بعض الأصناف الفرعية فقط. بعد إعادة التصميم نقل الحقل من الصنف الأب إلى الصنف الفرعي المستخدم فيه: نقل الحقل إلى هذه الأصناف الفرعية. لم إعادة التصميم؟ على الرغم من أنه كان من المقرر استخدام حقل بشكل عام لجميع الأصناف، في الواقع ...

إعادة تسمية التوابع (Rename Method)

المشكلة لا يعبِّر اسم التابع عن ما يقوم به. الحل إعادة تسمية التابع. مثال قبل إعادة التصميم لا يفسر اسم التابع ()getsnm في الصنف Customer ما يقوم به. لا يفسر اسم التابع ما يقوم به. بعد إعادة التصميم إعادة تسمية التابع ()getsnm إلى ()getSecondName الذي يصف ما يقوم به. يفسر اسم التابع ما يقوم به. لم إعادة التصميم؟ ربما كانت تسمية تابعٍ ما سيئة من البداية - على سبيل المثال، أنشأ شخصٌ ما التابع في عجلة ولم يهتم كفاية بتسميته ...

تبديل التابع إلى كائن التابع (Replace Method with Method Object)

المشكلة وجود تابعٍ طويلٍ بالكثير من المتغيِّرات المحليّة (local variables) المتداخلة والتي تحول دون تطبيق تقنية الحل باستخراج التابع (extract method). الحل نقل التابع إلى صنفٍ (class) مستقلٍ بحيث تصبح متغيِّراته المحليّة حقولًا (fields) لهذا الصنف، وتقسيم التابع بعد ذلك إلى عدّة توابع أصغر في الصنف ذاته. مثال قبل إعادة التصميم نلاحظ وجود العديد من المتغيِّرات المحليّة في التابع price()‎ بالإضافة إلى عملياتٍ أخرى قد تكون طويلةً ومعقَّدة: في لغة Java: class Order { //... public double price() ...

تغيير الاقتران ثنائي الاتجاه إلى أحادي الاتجاه (Change Bidirectional Association to Unidirectional)

المشكلة وجود اقتران ثنائي الاتجاه (bidirectional association) بين الأصناف، ولكن لا يستخدم أحد الأصناف الميزات الأخرى. الحل إزالة الاقتران غير المستخدم. مثال قبل إعادة التصميم وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer، ولكن لا يستخدم أحدهما ميزات الآخر: وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer. بعد إعادة التصميم يحتاج الصنفان Customer و Order أحدهما الآخر ولكن الاقتران بينهما أحادي الاتجاه: وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer. لم إعادة التصميم؟ يكون من الصعب المحافظة على الاقتران ثنائي الاتجاه ...

فصل الاستعلامات عن المُعدِّلات (Separate Query from Modifier)

المشكلة هل لديك تابعٌ يُعيد قيمةً ما ولكن يغيِّر أيضا شيئًا ما داخل الكائن؟ الحل تقسيم التابع إلى تابعَين منفصلَين. كما يمكن أن نتوقع، يجب على أحدهما أن يعيد القيمة ويُغيِّر الآخر الكائن. مثال قبل إعادة التصميم ينفذ التابع ()getTotlaOutstandingAndSetReadyForSummaries في الصنف Customer مهمتين، إذ يعيد قيمة ويضبط قيمة أخرى في الكائن: تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن. بعد إعادة التصميم فصل التابع التابع ()getTotlaOutstandingAndSetReadyForSummaries إلى تابعين هما: الأول ()getTotlaOutstanding لجلب قيمة، والآخر ()setReadyForSummaries لضبط حالةٍ في الكائن: ...

استخراج المتغيرات (Extract Variables)

المشكلة وجود تعبيرٍ (expression) معقِّد يصعُب فهمه. الحل وضع ناتج التعبير أو جزءٍ منه في متغيِّرات (variables) واضحةٍ تُسهِّل الفهم. مثال قبل إعادة التصميم نلاحظ وجود تعبيرٍ شرطيٍّ (conditional expression) معقَّدٍ وبعدّة أجزاء كما في الشيفرة الآتية: في لغة Java: void renderBanner() { if ((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0 ) { // افعل شيئًا ...

سحب متن المُنشِئ لأعلى (Pull Up Constructor Body)

المشكلة تحتوي الأصناف الفرعية على مُنشِئات لها شيفرة متطابقة في أغلبها. الحل إنشاء مُنشئ صنف أب ونقل الشيفرة المماثلة في الأصناف الفرعية إليه. استدعاء مُنشئ الصنف الأب في مُنشِئات الصنف الفرعي. مثال قبل إعادة التصميم احتواء الصنف الفرعي Manager المشتق من الصنف Employee على منشئ متطابق بنسبة كبيرة: في لغة Java: class Manager extends Employee { public Manager(String name, String id, int grade) { this.name = name; this.id = id; ...

تجزئة الشَرطيات (Decompose Conditional)

المشكلة يوجد شَرط مُعقد (if-then/else أو switch). الحل فصل الأجزاء المعقدة من الشَرط إلى توابع منفصلة: الشرط، then و else. مثال قبل إعادة التصميم وجود شرط معقد ناتج عن دمج شرطين باستعمال المعامل || الثنائي في البنية if: في لغة Java: if (date.before(SUMMER_START) || date.after(SUMMER_END)) { charge = quantity * winterRate + winterServiceCharge; } else { charge = quantity * summerRate; } في لغة C#‎: if (date < SUMMER_START || date > SUMMER_END) { charge = quantity * winterRate + winterServiceCharge; } else ...

دفع التابع لأسفل (Push Down Method)

المشكلة هل السلوك المُنفَّذ في الصنف الأب مُستخدمٌ في صنف فرعي واحد فقط (أو أكثر)؟ الحل نقل هذا السلوك إلى الأصناف الفرعية. مثال قبل إعادة التصميم التابع ()getFuel الموجود في الصنف Unit الأب مُستخدم في صنف فرعي واحد فقط الذي هو Tank: التابع الموجود في الصنف الأب مُستخدم في صنف فرعي واحد فقط. بعد إعادة التصميم نقل التابع ()getFuel من الصنف الأب إلى الصنف الفرعي المستخدم فيه: نقل هذا التابع إلى الصنف الفرعي الذي يُستخدم فيه. لم إعادة التصميم؟ في ...

تبديل رموز الأنواع بالحالة/الاستراتيجية (Replace Type Code with State/Strategy)

ما هو رمز النوع؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. وغالبًا ما تُعطَى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. المشكلة يؤثر نوع مُرمَّز على سلوك البرنامج ولكن لا يمكن استخدام الأصناف الفرعية للتخلص منه. الحل استبدال رمز النوع بكائن حالة. إذا كان من الضروري استبدال قيمة حقل برمز النوع، فسيكون ...

تجزئة المتغير المؤقت (Split Temporary Variable)

المشكلة وجود متغيِّرٍ محليّ يُستخدَم لتخزين عدّة قيمٍ مؤقتةٍ (مرحليّة) داخل التابع. الحل استخدام متغيِّراتٍ منفصلةٍ ومستقلّةٍ للقيم المختلفة، بحيث يكون كلَُ متغيِّرٍ مسؤولًا عن تخزين البيانات لمهمةٍ واحدةٍ فقط. مثال قبل إعادة التصميم نلاحظ في الشيفرة الآتية استخدام المتغيِّر temp لتخزين ناتج كلِّ من تعبيريّ المحيط والمساحة: في لغة Java: double temp = 2 * (height + width); System.out.println(temp); temp = height * width; System.out.println(temp); في لغة #C: double temp = 2 * (height + width); Console.WriteLine(temp); temp = height * width; Console.WriteLine(temp); في لغة PHP: $temp ...

تبديل رموز الأنواع بالأصناف (Replace Type Code with Class)

ما هو رمز النوع (type code)؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. غالبا ما تُعطى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. المشكلة يحتوي الصنف على حقل يحتوي على رموز الأنواع. ولا تُستخدم قيم هذا النوع في شروط المُشغِّل ولا تؤثر على سلوك البرنامج. الحل إنشاء صنف جديد واستخدام كائناته بدلًا ...

تبديل المتغير المؤقت إلى استدعاء(Replace Temp with Query)

المشكلة تخزين نتيجة تعبيرٍ ما (expression) في متغيِّر محليٍّ (local variable) لاستخدامه لاحقًا في الشيفرة. الحل نقل التعبير بأكمله إلى تابعٍ (method) مستقلٍ يعيد نتيجته، وعندها سيكون استدعاء هذا التابع بديلًا عن استخدام المتغيِّر (variable)، ومن الممكن أيضًا دمج هذا التابع مع توابع أخرى عند الحاجة للقيام بذلك. مثال قبل إعادة التصميم نلاحظ في الشيفرة الآتية وجود متغيِّرٍ مؤقتٍ باسم basePrice لتخزين القيمة الناتجة عن تنفيذ التعبير الرياضيّ بمعامل الجداء (أي المعامل *)، وسيُستخدَم هذا المتغيِّر لاحقًا في الأجزاء الشرطيّة ...

استخراج الأصناف الفائقة (Extract Superclass)

المشكلة وجود صنفين لهما حقول وتوابع مشتركة. الحل إنشاء صنف أب مشترك لهما ونقل جميع الحقول والتوابع المتطابقة إليه. مثال قبل إعادة التصميم يملك الصنفين Department و Employee توابعًا مشتركة فيما بينهما: وجود صنفين لهما حقول وتوابع مشتركة. بعد إعادة التصميم إنشاء صنف أب لهما يدعى Party يحوي التوابع المشتركة: إنشاء صنف فائق مشترك لهما ونقل جميع الحقول والتوابع المتطابقة إليه. لم إعادة التصميم؟ يحدث نوع من تكرار الشيفرة عندما يؤدي صنفان نفس المهام بنفس الطريقة أو بطرق مختلفة. وتتيح ...

استبدال المعامل بتوابع صريحة (Replace Parameter with Explicit Methods)

المشكلة ينقسم التابع إلى أجزاء، كل منها يتم تشغيله اعتمادًا على قيمة المعامل. الحل استخراج الأجزاء الفردية من التابع إلى توابعها الخاصة واستدعائها بدلًا من استدعاء التابع الأصلي. مثال قبل إعادة التصميم وجود تابع يدعى ()setValue يضبط قيمة الارتفاع والعرض بناءً على تمرير سلسلة نصية صريحة بذلك: في لغة Java: void setValue(String name, int value) { if (name.equals("height")) { height = value; return; } if (name.equals("width")) { width ...

استبدال التفويض بالتوريث (Replace Delegation with Inheritance)

المشكلة يحتوي الصنف على العديد من التوابع البسيطة التي تفوِّض إلى كل التوابع في صنفٍ آخر. الحل جعل الصنف مفوِّض وارث، الأمر الذي يجعل تابع التفويض غير ضروري. مثال قبل إعادة التصميم التابع الموجود في الصنف Employee مفوَّض إلى التابع ()getName في الصنف Person: يحتوي الصنف على العديد من التوابع البسيطة التي تفوِّض إلى كل التوابع في صنفٍ آخر. بعد إعادة التصميم جعل الصنف Employee يرث من الصنف Person والتخلص من التفويض: أصبح الصنف مفوِّض وارث، الأمر الذي يجعل تابع ...

التغليف الداخلي للحقول (Self Encapsulate Fields)

ملاحظة قبل البدء: تختلف هذه التقنية عن تقنية تغليف الحقول (Encapsulate Field) من حيث أنّها تُستخدَم لتغليف الحقول الخاصّة (أي المُحدَّدة بالكلمة المفتاحيّة private). المشكلة الوصول المباشر إلى الحقول الخاصّة (private fields) داخل الصنف (class). الحل إنشاء تابعي الوصول getter و setter للحقل الخاصّ ومنع الوصول إليه إلا عبرهما. مثال قبل إعادة التصميم يحتوي الصنف Range على الحقلين low و high من النوع الخاص (private) ونلاحظ الوصول إليهما مباشرةً داخل التابع includes في الشيفرة الآتية: في لغة Java: class Range ...

تبديل القيمة إلى مرجع (Change Value to Reference)

المشكلة وجود العديد من النُسَخ المتماثلة من صنفٍ واحدٍ تحتاج إلى استبدال كائنٍ واحدٍ بها. الحل تحويل الكائنات المتماثلة إلى كائن مرجعي واحد. مثال قبل إعادة التصميم مخطط يوضح وجود العديد من النُسَخ المتماثلة من الصنف Order: مخطط يوضح وجود العديد من النُسَخ المتماثلة من صنفٍ Order. بعد إعادة التصميم تحويل الكائنات المتماثلة إلى كائن مرجعي واحد: تحويل الكائنات المتماثلة إلى كائن مرجعي واحد. لم إعادة التصميم؟ في العديد من الأنظمة، يمكن تصنيف الكائنات على أنها إمَّا قيم أو مراجع. ...

تقديم التوكيد (Introduce Assertion)

المشكلة لكي يعمل جزء من الشيفرة البرمجية بشكل صحيح، يجب أن تتحقق بعض الشروط أو تكون القيم صحيحة. الحل استبدل هذه الافتراضات بنقاط تحقق خاصة بالتوكيد. مثال قبل إعادة التصميم تعريف دالة تعيد قيمة عددية - ثمتِّل حد النفقات - مع افتراض تحقق أحد أمرين دون التأكد من هما: في لغة Java: double getExpenseLimit() { // يجب أن يكون إما حدًا للنفقات أو مشروعًا أساسيًا return (expenseLimit != NULL_EXPENSE) ? expenseLimit: primaryProject.getMemberExpenseLimit(); } في ...

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