نتائج البحث
اذهب إلى التنقل
اذهب إلى البحث
أنماط المخرجات في Sass
بالرغم من أنّ النمط الافتراضي لمخرجات CSS في Sass لطيفٌ ويعكسُ بِنية المستند، إلا أنَّ الأذواق والاحتياجات تختلف من شخص لآخر، لذا تدعمُ Sass عدة أنماط أخرى. تسمح لك Sass بأن تختار بين أربعة أنماط مختلفة للإخراج عن طريق ضبط الخيار :style أو استخدام الراية --style في سطر الأوامر. ملاحظة: لا يدعم مصرّف Sass الذي يمكن تثبيت باستخدام مدير الحزم npm النمط :nested؛ إذا أردتَ استخدامه فثبت مصرّف Sass كما هو موضّح في صفحة تثبيت وضبط واستخدام Sass. النمط المتشعّب ...
خطوات إعادة التصميم (Refactoring)
تجري عملية إعادة التصميم (refactoring) عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية: الحصول على شيفرةٍ نظيفة (clean code) إن لم تصبح الشيفرة أنظف من بعد إعادة التصميم فهذا هدرٌ للوقت، ولكن ما السبب؟ يحدث كثيرًا أن تحيد عن سياق إعادة التصميم بتغييراتٍ تدريجيّة صغيرةٍ لتتجه نحو إجراء تغييرٍ كبيرٍ واحدٍ! وهذا خطأ ومن السهل الوقوع ...
أنماط الشيفرات المُتعارَف عليها ما بين مبرمجي Kotlin
تعرِض هذه الصفحة أنماط كتابة الشيفرات المُتعارَف عليها (conventions) من قِبل مبرمجي لغة Kotlin. تطبيق دليل التنسيق (Applying the Style Guide) لضبط المُنسِّق IntelliJ formatter بما يتوافق مع هذا الدليل يُنصَح بتثبيت إضافة Kotlin بالإصدار 1.2.20 (أو أي إصدارٍ أحدث) وضبط المّحرِّر بالانتقال إلى الإعدادات (Settings) ثمّ المُحرِّر (Editor) ثم نمط الشيفرة (Code Style) ثم Kotlin واختر "ضبط من..." Set from…"" في الزاوية اليمنى العُلويَّة ومن القائمة اختر الخيار Predefined style/Kotlin style guide. وللتأكد من تنسيق الشيفرة وفقًا لدليل Kotlin ...
أنماط الشيفرات المُتعارَف عليها ما بين مبرمجي Kotlin
تعرِض هذه الصفحة أنماط كتابة الشيفرات المُتعارَف عليها (conventions) من قِبل مبرمجي لغة Kotlin. تطبيق دليل التنسيق (Applying the Style Guide) لضبط المُنسِّق IntelliJ formatter بما يتوافق مع هذا الدليل يُنصَح بتثبيت إضافة Kotlin بالإصدار 1.2.20 (أو أي إصدارٍ أحدث) وضبط المّحرِّر بالانتقال إلى الإعدادات (Settings) ثمّ المُحرِّر (Editor) ثم نمط الشيفرة (Code Style) ثم Kotlin واختر "ضبط من..." Set from…"" في الزاوية اليمنى العُلويَّة ومن القائمة اختر الخيار Predefined style/Kotlin style guide. وللتأكد من تنسيق الشيفرة وفقًا لدليل Kotlin ...
استبدال المُنشئ بتابع التصميم (Replace Constructor with Factory Method)
المشكلة لديك مُنشئ (constructor) معقد يقوم بما هو أكثر من مجرد وضع قيم المعامل في حقول الكائن. الحل إنشاء تابع تصميم واستخدامه لاستبدال استدعاءات المُنشئ. مثال قبل إعادة التصميم وجود منشئ معقد للصنف Employee: في لغة Java: class Employee {
Employee(int type) {
this.type = type;
}
//...
}
في لغة C#: public class Employee
{
public Employee(int type)
{
this.type = type;
}
//...
}
في لغة PHP: class ...
تقنيات إعادة التصميم (Refactoring Techniques)
إنشاء التوابع تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية. يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة، وهذه التقنيات هي: استخراج التوابع (Extract Methods): والتي تتمثل بوجود أجزاء من الشيفرة يُمكن عزلها وتجميعها سويةً. دمج التوابع (Inline ...
مطابقة الأنماط باستخدام ميزات Bash
مدى المحارف Character Ranges خلافًا لأمر grep والتعابير النمطية (regular expressions) فإن لدينا حالات كثيرة لمطابقة الأنماط التي يمكنك إجراؤها في الصدفة مباشرة دون الحاجة إلى استخدام برنامج خارجي، فلعلك تعلم أن محرفي * و ? يطابقان أي نص أو محرف وحيد -على الترتيب-، ومن أجل مطابقة هذين المحرفيْن تحديدًا، ضع حول كل منهما علامات اقتباس مزدوجة: hsoub ~> touch "*"
hsoub ~> ls "*"
*
يمكنك استخدام الأقواس المربعة لمطابقة أي محرف أو مجموعة محارف بداخل تلك الأقواس إن فُصلت أزواج المحارف ...
متى تحتاج إعادة التصميم؟ (When to Refactor)
نحتاج إلى إعادة التصميم (قاعدة المرات الثلاث): عند قيامك بأيّة مهمةٍ للمرّة الأولى، فالمهم هو إنجازها والحصول على النتيجة وحسب. لدى قيامك بمهمةٍ مشابهةٍ للمرّة الثانية قد ترفض بادئ الأمر فكرة التكرار ولكنك ستجد نفسك تقوم بنفس العمل! عند قيامك بالمهمة للمرّة الثالثة، ستحتاج إعادة التصميم. عند إضافة ميّزةٍ (feature) جديدة تساعد عملية إعادة التصميم (refactoring) على فهم شيفرات المبرمجين الآخرين بشكلٍ أفضل، وعند العمل على الشيفرة غير الجيدة لأحدهم فعليك بإعادة تصميمها أولًا، وهذا ضروريٌّ إذ يصبح التحكُّم بالشيفرة ...
الصنف :link
الصنف الزائف :link في CSS (أي pseudo-class) يُمثِّل عنصرًا لم تتم زيارته من قبل، ويُطابِق جميع عناصر و <area> و <link> التي لها الخاصية href ولم تتم زيارتها بعد. a:link {
color: red;
}
الأنماط المُعرَّفة للصنف الزائف :link سيتم تجاوزها بأيّة أصناف زائفة تليها خاصة بالروابط (مثل :active أو :hover أو :visited) التي لها نفس درجة التحديد. ولتطبيق الأنماط تطبيقًا صحيحًا فضع قاعدة :link قبل جميع القواعد الخاصة بالروابط وفق الترتيب :link ثم :visited ثم :hover ثم :active. ملاحظة: استخدم ...
Document.enableStyleSheetsForSet()
يفعّل التّابع Document.enableStyleSheetsForSet() صفحات الأنماط التي توافق الاسم المُحدّد في مجموعة صفحات الأنماط الحاليّة، ويُعطّل جميع صفحات الأنماط الأخرى (عَدا تلك التي بدون عنوان، والتي تكون دائمًا مُفعّلة). البنية العامة document.enableStyleSheetsForSet(name)
name اسم صفحات الأنماط المرغوب تفعيلها. ستُفعّل جميع صفحات الأنماط التي توافق هذا الاسم، لكن ستُعطَّل جميع صفحات الأنماط الأخرى التي تملك عنوانًا. مرّر سلسلةً نصيّةً فارغةً لهذا المُعامل لتعطيل جميع صفحات الأنماط البديلة والمُفضّلة (دون صفحات الأنماط الدّائمة التي لا تملك خاصّية title). ملاحظات تُوافَقُ العناوين يكون حسّاسًا ...
Document.preferredStyleSheetSet
تُعيد مجموعة صفحات الأنماط المُفضّلة حسب ما ضبطه كاتب الصّفحة. وهي للقراءة فقط. البنية العامّة preferredStyleSheetSet = document.preferredStyleSheetSet
تُشير قيمة المتغيّر preferredStyleSheetSet إلى مجموعة صفحات الأنماط المُفضّلة من طرف كاتب الصّفحة. يُحدَّدُ هذا من خلال ترتيب تعريفات صفحات الأنماط وترويسة HTTP ذات العنوان Default-Style. إن لم تكن هناك مجموعة صفحات أنماط مُفضَّلة من طرف الكاتب، فستكون القيمة المُعادة سلسلةً نصية فارغة (""). مثال if (document.preferredStyleSheetSet) {
console.log("مجموعة صفحات الأنماط المُفضّلة هي:" + document.preferredStyleSheetSet);
} else {
console.log("لا توجد صفحة ...
Sass/@ rules
تدعم Sass جميع قواعد CSS التي تبدأ بالرمز @، فضلًا عن أخرى خاصَّة بلغة Sass تسمى بالتعليمات (directives). لهذه القواعد تأثيرات مختلفة في Sass سنفصلها بعد قليل. انظر أيضًا تعليمات التحكم (control directives) وتعليمات المخاليط (mixin directives). القاعدة @import توسّع Sass استخدامات القاعدة @import الخاصَّة بلغة CSS للسماح لها باستيراد ملفات SCSS وملفات Sass. ستُدمج جميع ملفات SCSS وملفات Sass المُستورَدة معًا في ملف CSS واحدٍ. إضافةً إلى ذلك، يمكن استخدام المتغيرات أو المخاليط (mixins) المُعرّفة في الملفات المستوردة في ...
استبدال الأصناف الفرعية بالحقول (Replace Subclass with Fields)
المشكلة لديك أصناف فرعية تختلف فقط في توابع (إعادة الثوابت) الخاصة بها. الحل استبدال التوابع بالحقول في الصنف الأب وحذف الأصناف الفرعية. مثال قبل إعادة التصميم لدينا الصنف Person الذي يحتوي على الصنفيين الفرعيين Male و Female؛ يختلف هذان الصنفان في القيمة المعادة فقط. يحتوي الصنف Person يحتوي على الصنفيين الفرعيين Male و Female. بعد إعادة التصميم وضع حقول في الصنف Person الأب مكان مقابلة لحقول الصنف الفرعي Male و Female ثم حذف هذان الصنفان. حذف الصنفان الفرعيان Male و ...
Document.selectedStyleSheetSet
تُعيد اسم مجموعة صفحات الأنماط الجاري استعمالها حاليًّا. البنية العامة currentStyleSheetSet = document.selectedStyleSheetSet
document.selectedStyleSheet = newStyleSheetSet
عند الإعادة، سيحمل المتغيّر currentStyleSheetSet اسم مجموعة صفحات الأنماط الجاري استعمالها حاليًّا، يُمكنك كذلك ضبط مجموعة صفحات الأنماط باستعمال هذه الخاصيّة. ضبط قيمة لهذه الخاصيّة مُكافئٌ لاستدعاء التّابع document.enableStyleSheetsForSet() باستخدام القيمة currentStyleSheetSet، ثمّ ضبط نفس القيمة للخاصية lastStyleSheetSet أيضًا. مُلاحظة: قيمة هذه الخاصيّة حيّة؛ تغيير الخاصيّة disabled على صفحات الأنماط سيُؤثّر على قيمة هذه الخاصيّة. مثال console.log("مجموعة صفحات الأنماط الجاري استعمالها حاليًّا:" + document.selectedStyleSheetSet);
document.selectedStyleSheetSet = ...
Document.styleSheetSets
تُعيد قائمة بمجموعات صفحات الأنماط المُتاحة على المُستند حاليًّا. البنية العامة sets = document.styleSheetSets
عند الإعادة، سيحمل المتغيّر sets قائمة بمجموعات صفحات الأنماط المُتاحة على المُستند حاليًّا. مثال لنَفرِض أنّ لدينا عنصر قائمة <ul> بالمُعرِّف "sheetList" (ID)، يُمكنك ملء هذه القائمة بأسماء مجموعات صفحات الأنماط المُتاحة بشيفرة مُشابهة لما يلي: var list = document.getElementById("sheetList");
var sheets = document.styleSheetSets;
list.innerHTML = "";
for (var i = 0; i < sheets.length; i++) {
var item = document.createElement("li");
item.innerHTML = sheets[i];
list.appendChild(item);
}
ملاحظات ...
Document.lastStyleSheetSet
تُعيد آخر مجموعة صفحات أنماط مُفعَّلة؛ تتغيّر قيمة هذه الخاصية كلّما تغيّرت قيمة الخاصية document.selectedStyleSheetSet. البنية العامة lastStyleSheetSet = document.lastStyleSheetSet
قيمة المتغير lastStyleSheetSet ستُشير إلى آخر مجموعة صفحات أنماط ضُبِطت. إن لم تتغيّر مجموعة صفحات الأنماط الحاليّة عبر تعيين قيمة للخاصيّة document.selectedStyleSheetSet، فإنّ القيمة المُعادة ستكون null. لاحظ بأن هذه القيمة لا تتغير عند استدعاء التّابع document.enableStyleSheetsForSet(). مثال var lastSheetSet = document.lastStyleSheetSet;
if (!lastSheetSet) {
lastSheetSet = "لم تتغير صفحة الأنماط بعد";
}
console.log("آخر مجموعة صفحة أنماط كانت: " + lastSheetSet);
انظر ...
تبديل القيمة إلى مرجع (Change Value to Reference)
المشكلة وجود العديد من النُسَخ المتماثلة من صنفٍ واحدٍ تحتاج إلى استبدال كائنٍ واحدٍ بها. الحل تحويل الكائنات المتماثلة إلى كائن مرجعي واحد. مثال قبل إعادة التصميم مخطط يوضح وجود العديد من النُسَخ المتماثلة من الصنف Order: مخطط يوضح وجود العديد من النُسَخ المتماثلة من صنفٍ Order. بعد إعادة التصميم تحويل الكائنات المتماثلة إلى كائن مرجعي واحد: تحويل الكائنات المتماثلة إلى كائن مرجعي واحد. لم إعادة التصميم؟ في العديد من الأنظمة، يمكن تصنيف الكائنات على أنها إمَّا قيم أو مراجع. ...
تبديل رموز الأنواع بالحالة/الاستراتيجية (Replace Type Code with State/Strategy)
ما هو رمز النوع؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. وغالبًا ما تُعطَى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. المشكلة يؤثر نوع مُرمَّز على سلوك البرنامج ولكن لا يمكن استخدام الأصناف الفرعية للتخلص منه. الحل استبدال رمز النوع بكائن حالة. إذا كان من الضروري استبدال قيمة حقل برمز النوع، فسيكون ...
التابع Regexp.union في روبي
يُعيد التابع union كائنًا من النوع Regexp، والذي يمثل اتحاد الأنماط المعطاة؛ أي أنه سيتطابق مع أي من تلك الأجزاء. يمكن أن تكون الأنماط المعطاة كائنات من النوع Regexp، وفي هذه الحالة سيتم الاحتفاظ بخياراتها، أو يمكن أن تكون سلاسل نصية. إذا لم يتم إعطاء أية أنماط، فسيعيد التابع union القيمة /(?!)/. السلوك سيكون غير محدد إذا احتوى أيُّ من الأنماط المعطاة على التقاط (capture). ملاحظة: ستحاول روبي تحويل المعاملات المُمررة للتابع union إلى تعبيرات نمطية حرفية ( regular expression literal) عبر التابع ...
العنصر
يُحدِّد العنصر <link> العلاقات بين المستند الحالي وبين مورد خارجي (external resource)؛ من استخدامات هذا الوسم تتضمن تعريف علاقة بين الصفحات للتنقل بينها، بيد أنَّ أكثر استخدامات هذا العنصر شيوعًا هو تضمين صفحات الأنماط. استخدام الشكل الآتي للعنصر <link> لتضمين صفحة أنماط في المستند: <link href="style.css" rel="stylesheet">
بطاقة العنصر تصنيفات المحتوى البيانات الوصفية المحتوى المسموح لا يوجد، فهذا العنصر فارغ. الوسم المختصر لمّا كان هذا العنصر فارغًا، فيجب توفير وسم البداية وحذف وسم النهاية. العناصر الأب أي عنصر يقبل وجود ...
حذف المعاملات (Remove Parameter)
المشكلة لا يُستخدم معاملٌ ما في متن التابع. الحل إزالة المعامل غير المستخدم. مثال قبل إعادة التصميم تعريف المعامل Date في بداية التابع ()getContact وعدم استخدامه. تعريف المعامل Date في بداية التابع ()getContact وعدم استخدامه. بعد إعادة التصميم إزالة المعامل Date من التابع ()getContact لعدم استخدامه: إزالة المعامل Date من التابع ()getContact. لم إعادة التصميم؟ يفرض كل معامل موجود في استدعاء التوابع على المبرمج أن يقرأه لمعرفة ما هي المعلومات الموجودة في هذا المعامل. وإذا كان المعامل غير مستخدم على ...
تحويل التوابع إلى معاملات (Parameterize Method)
المشكلة تؤدي توابع متعددة أعمالًا مماثلة تختلف فقط من حيث قيمها الداخلية أو أرقامها أو عملياتها. الحل تجميع هذه التوابع باستخدام معامل يُمرر القيمة الخاصة الضرورية. مثال قبل إعادة التصميم يؤدي التابعان ()fivePercentRaise و ()tenPercentRaise الغرض ذاته باختلاف النسبة المئوية المراد زيادتها للموظف Employee: يؤدي التابعان أعمالًا مماثلة تختلف فقط من حيث قيمها الداخلية أو أرقامها أو عملياتها. بعد إعادة التصميم تجميع التابعان السابقان في تابع واحد يدعى ()raise مع تمرير النسبة المئوية المتغيرة إليه: يجمع التابعين باستخدام معامل يُمرر ...
تبديل المرجع إلى قيمة (Change Reference to Value)
المشكلة وجود كائن مرجع صغير جدًا نادرًا ما يتغيَّر لتبرير إدارة دورة حياته. الحل تحويله إلى كائن قيمة (value object). مثال قبل إعادة التصميم مخطط يوضح كيفية ارتباط الصنفين Currency و Customer: مخطط يوضح كيفية ارتباط الصنفين Currency و Customer. بعد إعادة التصميم إعادة تصميم المخطط السابق للتتحول العلاقة الرابطة للصنفين Currency و Customer إلى علاقة has a (أي بمجرد وجود كائن Customer فلا بد من وجود كائن Currency له). مخطط يوضح كيفية ارتباط الصنفين Currency و Customer بعلاقة has ...
تكرار البيانات المرُاقَبة (Duplicate Observed Data)
المشكلة هل بيانات النطاق المخزَّنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟ إذًا، إليك الحل. الحل فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية (GUI). مثال قبل إعادة التصميم إليك المخطط التالي لبيانات نطاق مخزَّنة في أصناف والمسؤولة عن الواجهة الرسومية: بيانات النطاق مخزَّنة في أصناف. بعد إعادة التصميم يصبح المخطط السابق بالشكل التالي بعد إعادة التصميم: فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية. لم ...
هدم التسلسل الهرمي (Collapse Hierarchy)
المشكلة في التسلسل الهرمي لصنف، يكون صنفٌ فرعي هو عمليًا نفس صنفه الأب. الحل دمج الصنف الفرعي والصنف الأب. مثال قبل إعادة التصميم الصنف الفرعي Salesman هو عمليًّا نفس الصنف Employee له: الصنفٌ الفرعي هو عمليًا نفس صنفه الأب. بعد إعادة التصميم دمج الصنف الفرعي Salesman في الصنف الأب: دمج الصنف الفرعي والصنف الأب. لم إعادة التصميم؟ قد يؤدي نمو البرنامج مع مرور الوقت إلى أن يصبح كلٌ من الصنف الفرعي والصنف الأب تقريبًا نفس الشيء. فتُزال ميزة من الصنف ...
إعادة تسمية التوابع (Rename Method)
المشكلة لا يعبِّر اسم التابع عن ما يقوم به. الحل إعادة تسمية التابع. مثال قبل إعادة التصميم لا يفسر اسم التابع ()getsnm في الصنف Customer ما يقوم به. لا يفسر اسم التابع ما يقوم به. بعد إعادة التصميم إعادة تسمية التابع ()getsnm إلى ()getSecondName الذي يصف ما يقوم به. يفسر اسم التابع ما يقوم به. لم إعادة التصميم؟ ربما كانت تسمية تابعٍ ما سيئة من البداية - على سبيل المثال، أنشأ شخصٌ ما التابع في عجلة ولم يهتم كفاية بتسميته ...
ازالة توابع الإعدادات (Remove Setting Method)
المشكلة يكون تعيين قيمة الحقل فقط عند إنشائه، ولا تتغير في أي وقت لاحق. الحل إزالة التوابع التي تضبط قيمة الحقل. مثال قبل إعادة التصميم يضبط التابع ()setImmutableValue قيمةً غير قابلة للتغيير أو التعديل في المستقبل: يغيّر التابع من قيمة الحقل. بعد إعادة التصميم حذف التابع ()setImmutableValue من الصنف Customer: إزالة التابع الذي يضبط قيمة الحقل. لم إعادة التصميم؟ إذا كنت تريد منع أي تغييرات في قيمة الحقل. آلية الحل يجب أن تكون قيمة الحقل قابلة للتغيير فقط في الباني. ...
الوسيط (Middle Man)
توصيف المشكلة عندما يكون للصنف (class) مهمةٌ واحدةٌ فقط وهي تفويض المهام (delegation) لصنفٍ آخر، فما أهمية وجوده بالأصل؟ أسبابها قد تنتج المشكلة عن التخلُّص المفرط من الاستدعاءات المتسلسلة كعلاجٍ لمشكلة سلاسل الرسائل (message chains). أو قد تنتُج عن النقل التدريجيّ للصنف (class) إلى أصناف أخرى ليبقى الصنف الأصليّ فارغًا إلا من أوامر التفويض (delegation). وما الحل؟ حذف الوسيط (remove middle man) إن كانت معظم أصناف التابع (method's classes) تفوِّض المهام (delegate) إلى صنفٍ آخر. إليك المزيد ستحصل بحلِّ المشكلة ...
إضافة المعاملات (Add Parameter)
المشكلة لا يملك التابع بيانات كافية لتنفيذ بعض الإجراءات. الحل إنشاء معامل جديد لتمرير البيانات الضرورية. مثال قبل إعادة التصميم لا يملك التابع ()getContact في الصنف Customer لجدولة موعدٍ للتواصل مع الزبون: لا يملك التابع بيانات كافية لتنفيذ بعض الإجراءات. بعد إعادة التصميم أصبح بالإمكان تمرير تاريخ إلى التابع ()getContact لتصبح بيانات جدولة تاريخ مناسب مع الزبون مكتملة: إنشاء معامل جديد لتمرير البيانات الضرورية. لم إعادة التصميم؟ تحتاج إلى إجراء بعض تغييرات على أحد التوابع، وتتطلب هذه التغييرات إضافة معلومات ...
الحفاظ على الكائن كاملًا (Preserve Whole Object)
المشكلة جلب عدة قيم من أحد الكائنات، ثم تمريرها كمعاملات إلى أحد التوابع. الحل حاول تمرير الكائن بالكامل بدلًا من ذلك. مثال قبل إعادة التصميم جلب قيمة درجة الحرارة المنخفضة low والمرتفعة high من الكائن daysTempRange ثم تمريرهما إلى التابع ()withinTange: في لغة Java: int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);
في لغة C#: int low = daysTempRange.GetLow();
int high = daysTempRange.GetHigh();
bool withinPlan = plan.WithinRange(low, high);
في لغة PHP: $low = $daysTempRange->getLow();
$high = $daysTempRange->getHigh();
$withinPlan = $plan->withinRange($low, $high);
في لغة Python: ...
الوحدة File::Constants في روبي
توفر الوحدة File::Constants ثوابت متعلقة بالملفات في روبي. جميع ثوابت الملفات المحتملة موثَّقة هنا ولكن ليس بالضرورة أن تكون كلها متاحة على منصتك. إن كانت المنصة الأساسية لا تعرِّف ثابتًا ما، فلن يُعرَّف ثابت روبي المقابل له. قد تجد بعض المعلومات المفيدة في توثيقات المنصة التي تعمل عليها (مثل الدليل man للدالة open(2)). الثوابت APPEND الإضافة عند كل عملية كتابة. BINARY تعطيل تحويل الشيفرة السطري. CREAT إنشاء ملف إن لم يكن موجودًا. DIRECT محاولة تصغير ثأتيرات الذاكرة المخبَّأة (cache) للدخل ...
نقل الحقول (Move Fields)
المشكلة استخدام الحقل (field) في صنفٍ (class) ما أكثر من استخدامه في صنفه الأساسيّ. الحل إنشاء حقلٍ في صنفٍ جديدٍ وإعادة توجيه (redirect) كلَّ ما يستخدم هذا الحقل إلى ذلك الصنف المُنشَأ. مثال قبل إعادة التصميم يستخدِم الصنفُ Class2 الحقلَ aField أكثر مما يستخدمه صنفه الأساسيّ Class1: يستخدِم الصنفُ Class2 الحقلَ aField أكثر مما يستخدمه صنفه الأساسيّ Class1. بعد إعادة التصميم نُقِل الحقل aField إلى الصنف ذي الاستخدام الأكثر له وهو الصنف Class2: نُقِل الحقل aField إلى الصنف ذي الاستخدام ...
العنصر
يحتوي العنصر <style> معلومات عن تنسيق المستند أو جزءٍ منه، إذ تحتوى داخل هذا العنصر معلومات التنسيق التي من المتوقع أن تكون بلغة CSS. مثال بسيط عن العنصر <style> مع بعض تعليمات التنسيق داخله: <style>
body {
color: red;
}
</style>
بطاقة العنصر تصنيفات المحتوى البيانات الوصفية المحتوى المسموح محتوى نصي يُطابِق قيمة الخاصية type، ألا وهي text/css. الوسم المختصر لا يمكن حذف أيّ من وسمَي البداية أو النهاية العناصر الأب أي عنصر يقبل البيانات الوصفية. واجهة DOM HTMLStyleElement دعم المتصفحات Chrome ...
المخاليط (Mixins) في Sass
تتيحُ المخاليط تعريف الأنماط التي يمكن إعادة استخدامها في ملف الأنماط دون اللجوء إلى الأصناف غير الدلاليَّة مثلِ .float-left. يمكن أن تحوي المخاليط أيضًا جميع قواعد CSS وأيَّ شيء آخر يُسمح باستعماله في ملفات Sass. يمكن أيضًا أن يُمرَّر لها وسائط (arguments) وبذلك يمكن إنتاج مجموعة واسعة من الأنماط بعدد قليل من المخاليط. تعريف المخلوط (Defining a Mixin): @mixin تعرَّف المخاليط (Mixins) بوساطة التعليمة @mixin متبوعةً باسم المخلوط، ويمكن اختياريًا إضافة وسائط له، ثمّ كتلة من الأنماط تتضمّن محتويات المخلوط. ...
تجزئة الشَرطيات (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 ...
تعريف كائن المُعامل (Introduce Parameter Object)
المشكلة تحتوي التوابع على نفس المجموعة المتكررة من المعاملات. الحل استبدال هذه المعاملات بكائنٍ واحد. مثال قبل إعادة التصميم تمرير نفس مجموعة المعاملات إلى توابع الصنف Customer: تحتوي التوابع على نفس المجموعة المتكررة من المعاملات. بعد إعادة التصميم تبديل كائن واحد بتلك المعاملات وتمريره إلى توابع الصنف Customer التي تشترك بنفس مجموعة المعاملات: استبدال هذه المعاملات بكائنٍ واحد. لم إعادة التصميم؟ غالبًا ما تُصادَف مجموعات متطابقة من المعاملات داخل العديد من التوابع. الأمر الذي يؤدي إلى تكرار الشيفرة البرمجية للمعاملات ...
سحب التابع لأعلى (Pull Up Method)
المشكلة تحتوي الأصناف الفرعية على توابع تؤدي نفس العمل. الحل جعل التوابع متطابقة ثم نقلها إلى الصنف الأعلى ذي الصلة. مثال قبل إعادة التصميم يحتوي الصنفان الفرعيان Soldier و Tank على التابع ()getHealth الذي يؤدي نفس العمل: تحتوي الأصناف الفرعية على التابع ()getHealth تؤدي نفس العمل. بعد إعادة التصميم نقل التابع ()getHealth إلى الصنف Unit الأب وإزالته من الأصناف الفرعية: نقل التابع ()getHealth إلى الصنف الأعلى. لم إعادة التصميم؟ تنمو الأصناف الفرعية وتتطور بشكل مستقل عن بعضها البعض، مما يتسبب ...
استخراج التوابع (Extract Methods)
المشكلة وجود أجزاء من الشيفرة يُمكن عزلها وتجميعها سويةً. الحل نقل الشيفرة إلى تابعٍ (method) أو دالةٍ (function) جديدة والاستعاضة عن الجزء (بمكانه السابق) باستدعاءٍ لهذا التابع الجديد. مثال قبل إعادة التصميم نلاحظ وجود جزء من الشيفرة لطباعة بعض البيانات (التفاصيل)، والتي يمكن عزلها بتابعٍ جديد، الشيفرة قبل إعادة التصميم بالشكل: في لغة Java: void printOwing() {
printBanner();
// طباعة التفاصيل
System.out.println("name: " + name);
System.out.println("amount: " + getOutstanding());
}
في لغة #C: void PrintOwing()
{
PrintBanner();
...
تبديل قيم البيانات إلى كائنات (Replace Data Values with Objects)
المشكلة وجود حقلٍ (field) مٌخصَّص للبيانات في صنفٍ (class) ما (أو في عددٍ من الأصناف)، ولهذا الحقل بياناته وسلوكه (behaviour) المرتبط به. الحل إنشاء صنفٍ جديدٍ ليُوضَع فيه الحقل (field) بالإضافة إلى سلوكه المرتبط به، وتخزين كائنٍ (object) من هذا الصنف الجديد في الصنف الأصليّ للحقل. مثال قبل إعادة التصميم يحتوي الصنف Order على الحقل customer الذي يحتوي بيانات نصيّة (من النوع String) كما هو واضح في مخطط الأصناف الآتي: الصنف Order يحتوي على الحقل customer الذي يحتوي بيانات نصيّة. ...
دفع الحقل لأسفل (Push Down Field)
المشكلة هل يستخدم الحقل في بعض الأصناف الفرعية فقط؟ الحل نقل الحقل إلى هذه الأصناف الفرعية. مثال قبل إعادة التصميم يُستخدَم الحقل fuel الموجود في الصنف Unit الأب في صنف فرعي واحد فقط الذي هو Tank: يستخدم الحقل في بعض الأصناف الفرعية فقط. بعد إعادة التصميم نقل الحقل من الصنف الأب إلى الصنف الفرعي المستخدم فيه: نقل الحقل إلى هذه الأصناف الفرعية. لم إعادة التصميم؟ على الرغم من أنه كان من المقرر استخدام حقل بشكل عام لجميع الأصناف، في الواقع ...
HTML/Topics/Document Metadata
تحتوي البيانات الوصفية على معلومات عن الصفحة، التي تتضمن المعلومات حول الأنماط (styles) والسكربتات، والبيانات المُساعدة للبرمجيات (مثل محركات البحث والمتصفحات ...إلخ.) التي تستخدم الصفحة أو تعرضها. العنصر الوصف <base> تحديد أساس روابط URL لجميع الروابط النسبية (relative URLs) الموجودة في المستند. لا يجوز استخدام أكثر من عنصر <base> في المستند. <head> توفير معلوماتٍ عامةً عن المستند (أي بيانات وصفية)، بما في ذلك عنوان المستند وروابط إلى السكربتات الموجودة فيها وصفحات الأنماط. <link> تحديد العلاقات بين المستند الحالي وبين مورد خارجي (external resource)؛ ...
إزالة الإسناد إلى المعاملات (Remove Assignments to Parameters)
المشكلة إسناد قيمةٍ ما إلى أحد المعاملات (parameter) داخل التابع (method body). الحل استخدام متغيِّرٍ محليٍّ (local variable) بدلًا من المعامل. مثال قبل إعادة التصميم نلاحظ وجود عمليّة إسنادٍ (من بعد الإنقاص بمقدار 2) إلى معامل التابع الوارد باسم inputVal: في لغة Java: int discount(int inputVal, int quantity) {
if (inputVal > 50) {
inputVal -= 2;
}
//...
}
في لغة #C: int Discount(int inputVal, int quantity)
{
if (inputVal > 50)
...
القيمة المحددة
القيمة المُحدَّدة (specified value) لإحدى خاصيات CSS هي القيمة المضبوطة لتلك الخاصية، سواءً من صفحة الأنماط مباشرةً، أو من العنصر الأب، وتُعرَّف القيمة المُحدَّدة بطريقة من الطرائق الآتية: إذا كان لصفحة الأنماط المرتبطة بالمستند قيمةٌ للخاصية، فهذه هي القيمة المستخدمة، فمثلًا لو ضُبِطَت الخاصية color إلى green، فسيكون لون نص العنصر المُحدَّد هو اللون الأخضر. إذا لم تُحدِّد صفحة الأنماط المرتبطة بالمستند قيمة للخاصية، فسترثها من العنصر الأب إن كان ذلك ممكنًا، فمثلًا إذا كانت لدينا فقرة <p> داخل العنصر ...
التسلط على الكائنات الأخرى (Feature Envy)
توصيف المشكلة استخدام بعضُ التوابع (methods) بياناتِ الكائنات (objects) الأخرى أكثر ممّا تستخدم بياناتِها ذاتَها. أسبابها تحدث هذه المشكلة عقب نقل الحقول (fields) إلى أصناف البيانات (data class)، إذ من الأفضل نقلُ التوابع المستخدِمة لتلك الحقول لذلك الصنف أيضًا. وما الحل؟ لنضع بالحسبان القاعدة الآتية: يجب أن تبقى الأجزاء التي تتغيَّر بآنٍ واحدٍ في المكان ذاته معًاولتحقيق ذلك: نقلُ التوابع (move methods) إلى المكان الأنسب في الشيفرة. عندما يستخدِم جزءٌ فقط من التابع بياناتِ كائنٍ (object) آخر، فالأفضل استخراجُ تابعٍ ...
سحب الحقل لأعلى (Pull Up Field)
المشكلة يحتوي صنفان على نفس الحقل. الحل إزالة الحقل من الأصناف الفرعية ونقله إلى الصنف الأعلى. مثال قبل إعادة التصميم يحتوي الصنفان Tank و Soldier المتفرعان من الصنف Unit على الحقل المشترك health: يحتوي الصنفان Soldier و Tank على نفس الحقل health. بعد إعادة التصميم إزالة الحقل health من الأصناف الفرعية (الصنف Soldier والصنف Tank) ونقله إلى الصنف Unit الأب: إزالة الحقل health من الأصناف الفرعية ونُقل إلى الصنف الأب. لم إعادة التصميم؟ تنمو الأصناف الفرعية وتتطور بشكل منفصل، مما ...
Document.styleSheets
تُعيد الخاصيّة document.styleSheets القابلة للقراءة فقط قائمةً من النّوع StyleSheetList التي تُعدّ عناصرُها كائناتٍ من النّوع CSSStyleSheet، وهذه الكائنات تُمثّل صفحات الأنماط المربوطة صراحةً أو المُضمّنة في المُستند. البنية العامة var styleSheetList = document.styleSheets;
القيمة المُعادة قائمةٌ من النّوع StyleSheetList عناصِرها كائناتٌ من النّوع CSSStyleSheet. مثال function getStyleSheet(unique_title) {
for(var i=0; i<document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if(sheet.title == unique_title) {
return sheet;
}
...
توحيد التعبير الشرطي (Consolidate Conditional Expression)
المشكلة وجود عدة شروط تؤدي إلى نفس النتيجة أو الإجراء. الحل توحيد جميع هذه الشروط في تعبير وحيد. مثال قبل إعادة التصميم وجود عدة شروط يتم التحقق منها في الشيفرة: في لغة Java: double disabilityAmount() {
if (seniority < 2) {
return 0;
}
if (monthsDisabled > 12) {
return 0;
}
if (isPartTime) {
return 0;
}
// حساب مقدار العجز
//...
}
في ...
نقل التابع (Move Method)
المشكلة استخدام التابع (method) في صنفٍ (class) ما أكثر من استخدامه في صنفه الأساسيّ. الحل إنشاء تابعٍ جديدٍ في الصنف الأكثر استخدامًا لذلك التابع ونقل شيفرته إلى التابع الجديد، ثم تحويل الشيفرة في التابع الأصليّ إلى مرجعيّةٍ للتابع الجديد في الصنف الآخر أو حذفه كليَّا. مثال قبل إعادة التصميم يستخدِم الصنفُ Class2 التابعَ aMethod() أكثر مما يستخدمه صنفه الأساسيّ Class1: يستخدِم الصنفُ Class2 التابعَ aMethod() أكثر مما يستخدمه صنفه الأساسيّ Class1. بعد إعادة التصميم نُقِل التابع aMethod() إلى الصنف ذي ...
دمج المتغير المؤقت (Inline Temp)
المشكلة وجود متغيِّرٍ مؤقَّت (temporary) لحفظ قيمة تعبيرٍ (expression) بسيطٍ ولا شيء آخر سواه. الحل تبديل كلُّ مرجعيّةٍ (reference) للمتغيِّر ليحلَّ محلَّها التعبيرُ نفسه. مثال قبل إعادة التصميم نلاحظ في الشيفرة الآتية وجود متغيِّرٍ مؤقتٍ باسم basePrice لتخزين القيمة الناتجة عن تعبير استدعاء التابع order.basePrice()، والذي سيُستخدَم في التعليمة التالية لتعريفه: في لغة Java: boolean hasDiscount(Order order) {
double basePrice = order.basePrice();
return basePrice > 1000;
}
في لغة #C: bool HasDiscount(Order order)
{
double basePrice = order.BasePrice();
return ...
فصل الاستعلامات عن المُعدِّلات (Separate Query from Modifier)
المشكلة هل لديك تابعٌ يُعيد قيمةً ما ولكن يغيِّر أيضا شيئًا ما داخل الكائن؟ الحل تقسيم التابع إلى تابعَين منفصلَين. كما يمكن أن نتوقع، يجب على أحدهما أن يعيد القيمة ويُغيِّر الآخر الكائن. مثال قبل إعادة التصميم ينفذ التابع ()getTotlaOutstandingAndSetReadyForSummaries في الصنف Customer مهمتين، إذ يعيد قيمة ويضبط قيمة أخرى في الكائن: تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن. بعد إعادة التصميم فصل التابع التابع ()getTotlaOutstandingAndSetReadyForSummaries إلى تابعين هما: الأول ()getTotlaOutstanding لجلب قيمة، والآخر ()setReadyForSummaries لضبط حالةٍ في الكائن: ...
استخرج الواجهات (Extract Interface)
المشكلة يستخدم العديد من العملاء نفس الجزء من واجهة الصنف. حالة أخرى: عندما يوجد نفس الجزء من الواجهة في صنفين. الحل نقل هذا الجزء المتطابق إلى الواجهة الخاصة به. مثال قبل إعادة التصميم استخدام التابعين ()getRate و ()hasSpecialSkill في الصنف Employee بكثرة: يستخدم العديد من العملاء نفس الجزء من واجهة الصنف. بعد إعادة التصميم استخراج هذين التابعين إلى واجهة خاصة بهما تدعى Billable: تقل هذا الجزء المتطابق إلى الواجهة الخاصة به. لم إعادة التصميم؟ تكون الواجهات مناسبة جدًا عندما تلعب ...
إخفاء التابع (Hide Method)
المشكلة لا يُستخدم التابع من قِبل الأصناف الأخرى أو يستخدم فقط داخل التسلسل الهرمي للصنف الخاص به. الحل جعل التابع خاصًا أو محميًا. مثال قبل إعادة التصميم لا يستخدم التابع ()aMethod من قبل أصناف أخرى غير الصنف Employee المعرف فيه: لا يُستخدم التابع من قِبل الأصناف الأخرى أو يستخدم فقط داخل التسلسل الهرمي للصنف الخاص به. بعد إعادة التصميم جعل التابع ()aMethod خاصًّا ومحميًّا بإخفائه عن الأصناف الأخرى: جعل التابع خاصًا أو محميًا. لم إعادة التصميم؟ في كثير من الأحيان، ...
دفع التابع لأسفل (Push Down Method)
المشكلة هل السلوك المُنفَّذ في الصنف الأب مُستخدمٌ في صنف فرعي واحد فقط (أو أكثر)؟ الحل نقل هذا السلوك إلى الأصناف الفرعية. مثال قبل إعادة التصميم التابع ()getFuel الموجود في الصنف Unit الأب مُستخدم في صنف فرعي واحد فقط الذي هو Tank: التابع الموجود في الصنف الأب مُستخدم في صنف فرعي واحد فقط. بعد إعادة التصميم نقل التابع ()getFuel من الصنف الأب إلى الصنف الفرعي المستخدم فيه: نقل هذا التابع إلى الصنف الفرعي الذي يُستخدم فيه. لم إعادة التصميم؟ في ...
استخراج الأصناف الفائقة (Extract Superclass)
المشكلة وجود صنفين لهما حقول وتوابع مشتركة. الحل إنشاء صنف أب مشترك لهما ونقل جميع الحقول والتوابع المتطابقة إليه. مثال قبل إعادة التصميم يملك الصنفين Department و Employee توابعًا مشتركة فيما بينهما: وجود صنفين لهما حقول وتوابع مشتركة. بعد إعادة التصميم إنشاء صنف أب لهما يدعى Party يحوي التوابع المشتركة: إنشاء صنف فائق مشترك لهما ونقل جميع الحقول والتوابع المتطابقة إليه. لم إعادة التصميم؟ يحدث نوع من تكرار الشيفرة عندما يؤدي صنفان نفس المهام بنفس الطريقة أو بطرق مختلفة. وتتيح ...
HTML/Topics
تحتوي هذه الصفحة على قائمة بعناصر HTML، منظمةً حسب وظيفتها ليسهل عليك الوصول إلى مبتغاك. العنصر الجذر العنصر الوصف <html> تمثيل العنصر الرئيسي في مستندات HTML، ويُشار إليه أحيانًا باسم «العنصر الجذر» (root element). يجب أن تكون جميع العناصر الأخرى في المستند سليلةً (descendants، أي أبناء مباشرين وغير مباشرين) له. البيانات الوصفية تحتوي البيانات الوصفية على معلومات عن الصفحة، التي تتضمن المعلومات حول الأنماط (styles) والسكربتات، والبيانات المُساعدة للبرمجيات (مثل محركات البحث والمتصفحات ...إلخ.) التي تستخدم الصفحة أو تعرضها. العنصر الوصف ...
تبديل المصفوفات بكائنات (Replace Array with Object)
تقنية إعادة التصميم هذه هي حالة خاصة من تبديل قيم البيانات إلى كائنات. المشكلة لديك مصفوفة تحتوي على أنواع مختلفة من البيانات. الحل استبدال المصفوفة بكائن يكون له حقول منفصلة لكل عنصر. مثال قبل إعادة التصميم احتواء المصفوفة row على نوعين مختلفين من البيانات (سلسلة نصية وعدد): في لغة Java: String[] row = new String[2];
row[0] = "Liverpool";
row[1] = "15";
في لغة C#: string[] row = new string[2];
row[0] = "Liverpool";
row[1] = "15";
في لغة PHP: $row = array();
$row[0] = "Liverpool";
$row[1] = 15;
في لغة ...
تبديل رموز الأنواع بالأصناف الفرعية (Replace Type Code with Subclasses)
ما هو رمز النوع؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. وغالبًا ما تُعطَى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. المشكلة يؤثر النوع المُرمَّز على سلوك البرنامج (تُطلِق قيم هذا الحقل رموز مختلفة في الشرطيات). الحل إنشاء أصناف فرعية لكل قيمة من النوع المُرمَّز. ثم استخراج السلوكيات ذات الصلة من الصنف ...
تغيير الاقتران أحادي الاتجاه إلى ثنائي الاتجاه (Change Unidirectional Association to Bidirectional)
المشكلة وجود صنفان يحتاج كل منهما إلى استخدام ميزات الآخر، ولكن الاقتران بينهما أحادي الاتجاه فقط. الحل إضافة الاقتران المفقود إلى الصنف الذي يحتاج إليه. مثال قبل إعادة التصميم يحتاج الصنفان Customer و Order أحدهما الآخر ولكن الاقتران بينهما أحادي الاتجاه: الاقتران بين الصنفين أحادي الاتجاه فقط. بعد إعادة التصميم إضافة الاقتران الناقص إلى الصنف Customer: الاقتران المفقود مُضاف إلى الصنف الذي يحتاج إليه. لم إعادة التصميم؟ في الأصل، كان اقتران الأصناف أحادي الاتجاه. ولكن مع الوقت، احتاجت شيفرة العميل ...
الاستغناء عن الوسيط (Remove Middle Man)
المشكلة احتواء الصنف (class) على العديد من التوابع (methods) التي تنقل (delegate) سياق البرنامج إلى كائنات (objects) أخرى. الحل حذف تلك التوابع وإجبار العميل (client) على الاستدعاء المباشر للتوابع النهائية (التي سيصل إليها بالنهاية وتحتوي المهام الفعليّة). مثال قبل إعادة التصميم يتعامل صنف العميل (client class) مع صنفٍ واحدٍ فقط وهو الصنف Person، والذي بدوره يستدعي كائنًا من صنفٍ آخر باسم Department دون أن يكون العميل على علمٍ بتفاصيل ذلك الاستدعاء، كما هو واضح في مخطط الأصناف الآتي: مخطط يوضح ...
استبدال التفويض بالتوريث (Replace Delegation with Inheritance)
المشكلة يحتوي الصنف على العديد من التوابع البسيطة التي تفوِّض إلى كل التوابع في صنفٍ آخر. الحل جعل الصنف مفوِّض وارث، الأمر الذي يجعل تابع التفويض غير ضروري. مثال قبل إعادة التصميم التابع الموجود في الصنف Employee مفوَّض إلى التابع ()getName في الصنف Person: يحتوي الصنف على العديد من التوابع البسيطة التي تفوِّض إلى كل التوابع في صنفٍ آخر. بعد إعادة التصميم جعل الصنف Employee يرث من الصنف Person والتخلص من التفويض: أصبح الصنف مفوِّض وارث، الأمر الذي يجعل تابع ...
تبديل الأعداد السحرية بثوابت رمزية (Replace Magic Number with Symbolic Constant)
المشكلة تستخدم الشيفرة البرمجية عددًا له معنىً معين له. الحل استبدال هذا العدد بثابت له اسم يمكن قراءته ويشرح معنى العدد. مثال قبل إعادة التصميم تستخدم الشيفرة التالية العدد 9.81 بالشكل المجرَّد الذي يمثِّل ثابت الجاذبية الأرضية: في لغة Java: double potentialEnergy(double mass, double height) {
return mass * height * 9.81;
}
في لغة C#: double PotentialEnergy(double mass, double height)
{
return mass * height * 9.81;
}
في لغة PHP: function potentialEnergy($mass, $height) {
return $mass * $height * ...
تبديل الشرطيات بالتعدديّة الشكليّة (Replace Conditional with Polymorphism)
المشكلة وجود شروط تنفِّذ إجراءات مختلفة اعتمادًا على نوع الكائن أو خصائصه. الحل إنشاء أصناف فرعية مطابقة لفروع البنية الشرطية. ويُنشأ فيها تابع مشترك وتُنقل إليه الشيفرة البرمجية من الفرع المقابل من الشرطية. ثم تُستبدل البنية الشرطية باستدعاء التابع المناسب. وينتج عن ذلك تنفيذ سليم يتحقق من خلال التعدديّة الشكليّة اعتمادًا على صنف الكائن. مثال قبل إعادة التصميم الصنف Bird يحتوي على التابع getSpeed الذي باستعمال البنية الشرطية switch من النوع type لحساب السرعة بناءً على قيمته: في لغة Java: ...
تغليف الحقول (Encapsulate Field)
المشكلة لديك حقل عام. الحل جعل الحقل خاصًّا وإنشاء توابع وصول له. مثال قبل إعادة التصميم وجود الحقل العام name في الصنف Person: في لغة Java: class Person {
public String name;
}
في لغة C#: class Person
{
public string name;
}
في لغة PHP: public $name;
في لغة TypeScript: class Person {
name: string;
}
بعد إعادة التصميم جعل الحقل name خاصًّا وإنشاء تابع جلب getName وضبط setName له: في لغة Java: class Person {
private String name;
public ...
استبدال شيفرات الأخطاء باستثناءات (Replace Error Code with Exception)
المشكلة يعيد التابع قيمة خاصة تشير إلى خطأ. الحل إطلاق استثناء بدلًا من ذلك. مثال قبل إعادة التصميم يعيد التابع ()withdraw القيمة 1- التي تمثِّل خطأً إن تحقق شرط محدَّد: في لغة Java: int withdraw(int amount) {
if (amount > _balance) {
return -1;
}
else {
balance -= amount;
return 0;
}
}
في لغة C#: int Withdraw(int amount)
{
if (amount > _balance)
{
...
التابع MatchData.eql? في روبي
يتحقق التابع eql? من تساوي كائنين من النوع matchdata، إذ يعيد القيمة true إذا كانت السلاسل النصية المستهدفة منهما، والأنماط ومواضع المُطابقة متماثلة. البنية العامة eql?(mtch2)→ true or false
المعاملات mtch2 الطرف الثاني في عملية الموازنة. القيمة المعادة تعاد القيمة true إذا كان الكائنان المتطابقان الموازنة بينهما متساويين، وإلا فستُعاد القيمة false. انظر أيضا المعامل==: يتحقق من تطابق كائنان من النوع matchdata إذا كانت السلاسل النصية المستهدفة منهما، والأنماط ومواضع المُطابقة متماثلة. مصادر قسم التابع eql? في الصنف MatchData في توثيق روبي ...
توحيد الأجزاء الشرطية المكررة (Consolidate Duplicate Conditional Fragments)
المشكلة شيفرة برمجية متطابقة موجودة في جميع فروع الشَرطيات. الحل نقل الشيفرة البرمجية خارج الشَرطية. مثال قبل إعادة التصميم استدعاء وتنفيذ الدالة ()send في نهاية جميع فروع الكتلة if الشرطية سواءً أكان الشرط محققًا أم لا: في لغة Java: if (isSpecialDeal()) {
total = price * 0.95;
send();
}
else {
total = price * 0.98;
send();
}
في لغة C#: if (IsSpecialDeal())
{
total = price * 0.95;
Send();
}
else
{
total = price * 0.98;
...
دمج الصنف (Inline Class)
المشكلة وجود صنفٍ (class) لا يقوم بأيّ مهمّة فعليّة ولا يُخطَّط لإضافة مهامٍ إليه لاحقًا. الحل نقل كافّة الميّزات (features) من هذا الصنف إلى صنفٍ آخر. مثال قبل إعادة التصميم يحتوي الصنف Person على حقلٍ واحدٍ باسم name وتابعٍٍ للحصول على رقم الهاتف getTelephoneNumber ولاشيء آخر، أمّا الصنف TelephoneNumber فهو يحتوي على حقلين باسم officeAreaCode و officeNumber بالإضافة إلى التابع السابق getTelephoneNumber، كما هو موضَّحٌ في مخطط الأصناف الآتي: الصنف Person يحتوي على حقلٍ واحدٍ باسم name وتابعٍٍ للحصول على ...
القاعدة @media
القاعدة @media في CSS يمكن أن تستعمل لتطبيق الأنماط بناءً على شروط معيّنة (تسمى media queries)، التي تختبر نوع الجهاز، وخصائصه، وبيئة التشغيل. لاحظ أنَّ بالإمكان وضع القاعدة @media داخل قواعد At-rules الأخرى، مثل القاعدة @supports. @media screen and (min-width: 900px) {
article {
padding: 1rem 3rem;
}
}
@supports (display: flex) {
@media screen and (min-width: 900px) {
article {
display: flex;
}
...
الأصناف الخاملة (Lazy Classes)
توصيف المشكلة وجود بعض الأصناف (classes) قليلة الاستخدام ولا أهمية لها في البرنامج، ويجدر التخلُّص منها إذ إنّ فهم وصيانة الأصناف يكلِّفان الوقت والجهد. أسبابها يكون تصميم الصنف بدايةً لأداء مهامٍ (functionality) معيّنة، ولكنّه قد يصبح صغيرًا لا أهميّة له من بعد الكثير من عمليات إعادة التصميم (refactoring). قد تُخصَّص بعض الأصناف لدعم التطوير المستقبلي للبرنامج (كالتخطيط المُسبق لميّزاتٍ ستُضاف لاحقًا)، وتصبح تلك الأصناف خاملةً عندما لا يحدث أيُّ تطويرٍ فيما بعد. وما الحل؟ تضمين الأصناف (inline classes) للعناصر (components) ...
التعابير النمطية المتوافقة مع لغة Perl أو (PCRE)
مقدمة تشبه صياغة الأنماط المستخدمة في هذه الدوال إلى حد كبير نفس صياغتها في لغة بيرل Perl. على سبيل المثال، يجب تضمين التعبير بين فاصلين (delimiters)، الشرطة المائلة للأمام (/) (slash). يمكن أن تكون الفواصل أي حرف ASCII غير هجائي رقمي، وليس مسافة فارغة باستثناء الشَرطة المائلة العكسية (\) (backslash) أو البايت الفارغ (null byte). إذا كان يجب استخدام الحرف الفاصل في التعبير نفسه، يجب تهريبه بواسطة الشَرطة المائلة العكسية (\). قد يتبع فاصلُ النهاية العديدَ من المُعدِّلات (modifiers) التي ...
تعليمات التحكم في Sass
تدعم SassScript تعليمات وتعابير التحكم التي تُستعمل لرَهن تفعيل الأنماط بشروط معيّنةٍ أو لتضمين نفس النمط لكن مع تطبيق بعض التنويعات عليه. ملاحظة: تعليمات التحكم هي ميزة متقدمةٌ، كما أنّها غير شائعة الاستخدام. وُجدت أساسًا لتُستعمل في المخاليط (mixins)، لاسيما تلك التي هي جزءٌ من المكتبات مثل Compass، لذلك فهي تتطلب مرونةً كبيرةً في التعامل معها. if() تُعيد الدالة المضمّنة if() إحدى قيمتين محدَّدتين بناءً على شرط معيّن، ويمكن استخدامها في أيّ سياق برمجي. لا تتحقق الدالة if إلا من ...
تبديل التابع إلى كائن التابع (Replace Method with Method Object)
المشكلة وجود تابعٍ طويلٍ بالكثير من المتغيِّرات المحليّة (local variables) المتداخلة والتي تحول دون تطبيق تقنية الحل باستخراج التابع (extract method). الحل نقل التابع إلى صنفٍ (class) مستقلٍ بحيث تصبح متغيِّراته المحليّة حقولًا (fields) لهذا الصنف، وتقسيم التابع بعد ذلك إلى عدّة توابع أصغر في الصنف ذاته. مثال قبل إعادة التصميم نلاحظ وجود العديد من المتغيِّرات المحليّة في التابع price() بالإضافة إلى عملياتٍ أخرى قد تكون طويلةً ومعقَّدة: في لغة Java: class Order {
//...
public double price() ...
استخراج الصنف (Extract Class)
المشكلة وجود صنفٍ (class) واحدٍ يقوم بمهامٍ عديدةٍ يمكن توزيعها على صنفين. الحل إنشاء صنفٍ جديدٍ ونقل بعض الحقول (fields) والتوابع (methods) إليه، والتي تتعلَّق بالمهام الوظيفيّة (functionality) لهذا الصنف الجديد. مثال قبل إعادة التصميم يحتوي الصنف Person على عددٍ من الحقول كاسم الشخص (name) ورمز منطقة المكتب (officeAreaCode) ورقمه (officeNumber)، وتابعًا للحصول على هذا الرقم باسم getTelephoneNumber، كما في مخطط الأصناف الآتي: الصنف Person يحتوي على عددٍ من الحقول كاسم الشخص (name) ورمز منطقة المكتب (officeAreaCode) ورقمه (officeNumber)، وتابعًا ...
سحب متن المُنشِئ لأعلى (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;
...
إخفاء التفويض (Hide Delegate)
المشكلة يصل العميل (client) إلى كائنٍ (object) ما وليكن الكائن B من أحد حقول (fields) أو توابع (methods) كائنٍ آخر وليكن A، ومن ثمّ يستدعي تابعًا لهذا الكائن B. الحل إنشاء تابعٍ جديدٍ في الصنف A والذي يُفضي إلى استدعاءٍ للكائن B، وبهذا لن يعلم العميل تفاصيل التفويض (delegation) للكائن B ولن يعتمد على ذلك. مثال قبل إعادة التصميم يتعامل صنف العميل (client class) مع صنفين، الأول صنف الأقسام (Department) والثاني صنف الأشخاص (Person) واللذان يحتويان تابعين للحصول على كائنٍ ...
دمج التوابع (Inline Methods)
المشكلة أن يكون محتوى التابع (method body) بسيطًا وواضحًا أكثر من التابع بحدِّ ذاته، ويمكن عندئذٍ الاستغناء عنه. الحل نقل الشيفرة الموجودة في التابع (محتوى التابع) إلى مواقع استدعائه، وحذف التابع برمته إذ لا داعي له. مثال قبل إعادة التصميم نلاحظ أن محتوى التابع moreThanFiveLateDeliveries() واضحٌ وبسيطٌ لدرجةٍ تجعل الاستغناء عنه ممكنًا: في لغة Java: class PizzaDelivery {
//...
int getRating() {
return moreThanFiveLateDeliveries() ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
...
تغيير الاقتران ثنائي الاتجاه إلى أحادي الاتجاه (Change Bidirectional Association to Unidirectional)
المشكلة وجود اقتران ثنائي الاتجاه (bidirectional association) بين الأصناف، ولكن لا يستخدم أحد الأصناف الميزات الأخرى. الحل إزالة الاقتران غير المستخدم. مثال قبل إعادة التصميم وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer، ولكن لا يستخدم أحدهما ميزات الآخر: وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer. بعد إعادة التصميم يحتاج الصنفان Customer و Order أحدهما الآخر ولكن الاقتران بينهما أحادي الاتجاه: وجود اقتران ثنائي الاتجاه بين الصنفين Order و Customer. لم إعادة التصميم؟ يكون من الصعب المحافظة على الاقتران ثنائي الاتجاه ...
استبدال المعامل بتوابع صريحة (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 ...
الشيفرة النظيفة (Clean Code)
تهدف عملية إعادة التصميم (refactoring) للتخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ مُبسَّط، وهذا -لا بُدَّ- أمرٌ رائعٌ ولكن بالبداية؛ ما معنى أن تكون الشيفرة نظيفةً؟ مميزات الشيفرة النظيفة فيما يأتي بعضٌ مما يميز الشيفرة النظيفة: واضحةٌ ومقروءةٌ للمبرمجين الآخرين إنّ ما يجعل الشيفرات أكثر تعقيدًا (بعيدَا عن الخوارزميّات فائقة التعقيد) هو اعتمادها على تسمية المتغيِّرات تسميةً ضعيفةً (غير منطقيّةٍ أو بدون معنى) أو احتوائها على أصناف (classes) ...
CSS/Topics/Pseudo Elements
العنصر الوصف ::after هو آخر عنصر ابن للعنصر المُحدَّد، ويستخدَم عادةً لإضافة محتوى تزييني للعنصر باستخدام الخاصية content، وهو عنصرٌ سطريٌ افتراضيًا. ::backdrop هو صندوقٌ يُعرَض مباشرةً تحت أيّ عنصر معروض في وضع ملء الشاشة. ::before هو أوّل عنصر ابن للعنصر المُحدَّد، ويستخدَم عادةً لإضافة محتوى تزييني للعنصر باستخدام الخاصية content، وهو عنصرٌ سطريٌ افتراضيًا. ::first-letter يؤدي إلى تطبيق الأنماط على أوّل حرف من أوّل سطر من العناصر الكتلية (block-level elements)، شرط ألّا يسبقها محتوى آخر (مثل الصور أو الجداول السطرية). ::first-line ...
التعابير النمطية في Bash
يلقي هذا الباب الضوء على المزايا المُضمَّنة في Bash لمطابقة الأنماط (patterns) والتعرف على فئات المحارف ومداها. إضافة إلى تفصيل للتعابير النمطية (Regular Expressions)، إذ هي أدوات قوية لاختيار أسطر بعينها من ملفات أو من مُخرج ما، وتستخدمها أوامر كثيرة في يونكس مثل vim و perl وقاعدة بيانات PotgreSQL وغيرها، كما يمكن إضافتها في أي لغة أو تطبيق باستخدام مكتبات خارجية، بل قد تجدها في أنظمة غير أنظمة يونكس، إذ يستخدمها برنامج Excel للجداول الذي يأتي في حزمة مكتب ويندوز. ...
الأعباء التقنية (Technical Debt)
يبذل المبرمج عادةً ما بوسعه لكتابة شيفرةٍ جيدةٍ، ولا ينوي أبدًا -أيًّا كان المبرمج- الحصولَ على شيفرةٍ رديئةٍ تكون السبب في فشل مشروعه البرمجيّ، لذا فلنطرح السؤال: ما هو الحدُّ الذي تصبح عنده الشيفرةُ النظيفةُ رديئةً؟ فخ الأعباء التقنية اقتُرح مصطلح "الأعباء أو الالتزامات التقنيّة" (ويقابله بالانكليزيّة Technical Debt) للمرّة الأولى من قِبل Ward Cunningham، فإنه لدى اقتراضك مبلغًا ماليًا من أحد المصارف تكبُر أمامك فرصة الشراء بشكلٍ أسرع، ويحدث أن تدفعَ علاوةً (وأيّ إضافات أخرى) لتسريع الأمر والحصول على ...
تبديل رموز الأنواع بالأصناف (Replace Type Code with Class)
ما هو رمز النوع (type code)؟ يحدث رمز النوع عندما يوجد مجموعة من الأرقام أو السلاسل النصية التي تشكل قائمة بالقيم المسموح بها لبعض العناصر بدلًا من استخدام نوع بيانات منفصل. غالبا ما تُعطى هذه الأرقام والسلاسل المحددة أسماءً مفهومة عن طريق الثوابت، وهو السبب في استخدام هذه الرموز بشكل كبير. المشكلة يحتوي الصنف على حقل يحتوي على رموز الأنواع. ولا تُستخدم قيم هذا النوع في شروط المُشغِّل ولا تؤثر على سلوك البرنامج. الحل إنشاء صنف جديد واستخدام كائناته بدلًا ...
استبدال الاستثناءات بالاختبارات (Replace Exception with Test)
المشكلة إطلاق استثناء يمكن لاختبار بسيط أن يحل محله. الحل يستعاض عن الاستثناء باختبار الحالة. مثال قبل إعادة التصميم معالجة الاستثناء الحاصل عند وقوع الفهرس periodNumber خارج حدود مصفوفة القيم values وإعادة القيمة 0 آنذاك: في لغة Java: double getValueForPeriod(int periodNumber) {
try {
return values[periodNumber];
} catch (ArrayIndexOutOfBoundsException e) {
return 0;
}
}
في لغة C#: double GetValueForPeriod(int periodNumber)
{
try
{
return values[periodNumber];
...
استبدال الخوارزمية (Substitute Algorithm)
المشكلة الحاجة إلى استبدال خوارزميّة ما بخوارزميّة أخرى. الحل تعديل محتوى التابع (method body) الذي يُنفِّذ الخوارزمية السابقة ليُنفِّذ الخوارزمية الجديدة. مثال قبل إعادة التصميم تتلخَّص مهمة التابع foundPerson بالبحث عن الأشخاص ذوي الأسماء "Don" أو "John" أو "Kent" وذلك بالمرور بعناصر المصفوفة النصّيّة people باستخدام حلقة for كما في الشيفرة: في لغة Java: String foundPerson(String[] people){
for (int i = 0; i < people.length; i++) {
if (people[i].equals("Don")){
return "Don";
...
تبديل المتغير المؤقت إلى استدعاء(Replace Temp with Query)
المشكلة تخزين نتيجة تعبيرٍ ما (expression) في متغيِّر محليٍّ (local variable) لاستخدامه لاحقًا في الشيفرة. الحل نقل التعبير بأكمله إلى تابعٍ (method) مستقلٍ يعيد نتيجته، وعندها سيكون استدعاء هذا التابع بديلًا عن استخدام المتغيِّر (variable)، ومن الممكن أيضًا دمج هذا التابع مع توابع أخرى عند الحاجة للقيام بذلك. مثال قبل إعادة التصميم نلاحظ في الشيفرة الآتية وجود متغيِّرٍ مؤقتٍ باسم basePrice لتخزين القيمة الناتجة عن تنفيذ التعبير الرياضيّ بمعامل الجداء (أي المعامل *)، وسيُستخدَم هذا المتغيِّر لاحقًا في الأجزاء الشرطيّة ...
التابع String.gsub! في روبي
يبدل التابع gsub! قيمة (أو قيم) محدَّدة مكان جميع الأنماط المتطابقة في السلسلة النصية التي استدعي معها. هذا التابع مماثل تمامًا للتابع gsub ولكن يعدل على السلسلة المعطاة نفسها. البنية العامة gsub!(pattern, replacement) → str or nil
gsub!(pattern, hash) → str or nil
gsub!(pattern) {|match| block } → str or nil
gsub!(pattern) → an_enumerator
المعاملات pattern يكون عادةً تعبيرًا نمطيًّا. إن كان سلسلة نصية، فستُفسَّر أية محارف خاصة بالتعبيرات النمطية الموجودة فيها حرفيًّا؛ أي '\\d' سيطابق خط مائل عكسي يتبعه الحرف 'd' مباشرةً ...
تبديل المعاملات باستدعاءات التوابع (Replace Parameter with Method Call)
المشكلة استدعاء تابع استعلام (query method) وتمرير نتائجه كمعاملات لتابع آخر، في حين أنه يمكن لهذا التابع استدعاء الاستعلام مباشرة. الحل بدلًا من تمرير القيمة من خلال المعامل، حاول وضع استدعاء الاستعلام داخل متن التابع. مثال قبل إعادة التصميم تخزين القيمة التي يعيدها كلٌّ من التابعين ()getSeasonalDiscount و ()getFees في متغير ثم تمريرها إلى التابع ()discountedPrice: في لغة Java: int basePrice = quantity * itemPrice;
double seasonDiscount = this.getSeasonalDiscount();
double fees = this.getFees();
double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);
في لغة C#: int basePrice ...
تعريف الإضافات محليًّا (Introduce Local Extensions)
المشكلة الحاجة إلى بعض التوابع (methods) غير الموجودة في الصنف المساعد (utility class)، ومن غير الممكن إضافتها إلى ذلك الصنف. الحل إنشاء صنفٍ (class) جديدٍ يحتوي التوابع اللازمة، وجعله كصنف تغليفٍ (wrapper) للصنف المساعد أو كصنفٍ فرعيٍّ (subclass) له. مثال قبل إعادة التصميم يعتمد صنف العميل ClientClass على الصنف المساعد Date ولكنّه بحاجة إلى بعض التوابع غير الموجودة فيه (كتابع الحصول على اليوم التالي مثلًا): الصنف العميل ClientClass الذي يعتمد على الصنف المساعد Date. بعد إعادة التصميم أصبح هنالك صنف ...
تجزئة المتغير المؤقت (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 ...
تقديم التوكيد (Introduce Assertion)
المشكلة لكي يعمل جزء من الشيفرة البرمجية بشكل صحيح، يجب أن تتحقق بعض الشروط أو تكون القيم صحيحة. الحل استبدل هذه الافتراضات بنقاط تحقق خاصة بالتوكيد. مثال قبل إعادة التصميم تعريف دالة تعيد قيمة عددية - ثمتِّل حد النفقات - مع افتراض تحقق أحد أمرين دون التأكد من هما: في لغة Java: double getExpenseLimit() {
// يجب أن يكون إما حدًا للنفقات أو مشروعًا أساسيًا
return (expenseLimit != NULL_EXPENSE) ?
expenseLimit:
primaryProject.getMemberExpenseLimit();
}
في ...
Python/PEP
يعبر الاختصار PEP عن العبارة Python Enhancement Propsoal وتعني اقتراح تحسين في بايثون، وهو وثيقة تصميم تقدّم معلومات لمجتمع بايثون، أو تصف ميزة جديدة في بايثون أو عملياتها أو البيئة الخاصة بها. يجب أن يقدم اقتراح التحسين مواصفات تقنية موجزة ووافية للميزة مع شرح للمنطق الخاص بها. المرجع الصفحة المرجعية لاقتراحات التعديل
تعريف التوابع الدخيلة (Introduce Foreign Methods)
المشكلة الحاجة إلى تابعٍ غير موجودٍ في الصنف المساعد (utility class) ومن غير الممكن إضافته إلى ذلك الصنف. الحل إضافة التابع المطلوب إلى صنف العميل (client class) وتمرير كائنٍ (object) من الصنف المساعد إليه كوسيط (argument). مثال قبل إعادة التصميم يحتوي الصنف Report تابعًا باسم sendReport والذي يستخدم الصنف المساعد Date لإنشاء تاريخ اليوم التالي عبر إضافة القيمة 1 إلى اليوم الحالي، كما يلي: في لغة Java: class Report {
//...
void sendReport() {
Date ...
String.prototype.replace()
الدالة String.prototype.replace() تُعيد سلسلةً نصيةً جديدةً فيها بعض أو جميع الأجزاء المُطابَقة عبر النمط pattern قد استبدلتها السلسلة النصية replacement. لاحظ أنَّ النمط pattern يمكن أن يكون سلسلةً نصيةً أو كائن RegExp، ويمكن أن يكون الوسيط replacement سلسلةً نصيةً أو دالةً التي ستُستدعى لكل مُطابَقة. لاحظ أنَّ السلسلة النصية الأصلية ستبقى دون تعديل. البنية العامة str.replace(regexp|substr, newSubstr|function)
regexp (أي pattern) كائن RegExp الذي ستبدّل الأجزاء المُطابَقة به إلى السلسلة النصية newSubStr أو بالقيمة المعادة من الدالة function. substr (أي pattern) ...
الخاصية background-blend-mode
الخاصية background-attachment في CSS تصف كيف يجب أن تمتزج صور الخلفية مع بعضها بعضًا ومع لون الخلفية المُحدَّد للعنصر. يجب تعريف أنماط الامتزاج (blending modes) بنفس ترتيب ورود الصور في خاصية background-image؛ وإذا لم يكن طول قائمة القيم في كلا الخاصيتين متساوٍ، فستُكرَّر أو تحذف بعض القيم حتى تتساوى فيما بينها. لاحظ أنَّه إذا استخدمنا الخاصية background المختصرة، فستؤدي إلى إعادة ضبط قيمة الخاصية background-blend-mode إلى قيمتها الافتراضية، لذا احرص على استعمال هذه الخاصية بعدها. بطاقة الخاصية القيمة الابتدائية normal ...
الصنف :visited
الصنف الزائف :visited في CSS (أي pseudo-class) يُمثِّل عنصرًا تمت زيارته من قبل، ولأسباب تابعة للخصوصية فإنَّ عدد الخاصيات التي يمكن تغيير قيمتها باستخدام هذا المُحدِّد قليلةٌ جدًا. a:visited {
color: green;
}
الأنماط المُعرَّفة للصنف الزائف :visited سيتم تجاوزها بأيّة أصناف زائفة تليها خاصة بالروابط (مثل :active أو :hover أو :link) التي لها نفس درجة التحديد. ولتطبيق الأنماط تطبيقًا صحيحًا فضع قاعدة :visited بعد قاعدة :link لكن قبل بقية القواعد الخاصة بالروابط وفق الترتيب :link ثم :visited ثم :hover ثم ...
الصنف :indeterminate
الصنف الزائف :indeterminate في CSS (أي pseudo-class) يُمثِّل أيّة نماذج تكون حالتها غير معروفة (indeterminate): input:indeterminate {
background: lime;
}
يمكن أن يُطابِق هذا المُحدَّد العناصر الآتية: صندوق تأشير checkbox الذي ضُبِطَت الخاصية indeterminate فيه إلى true عبر JavaScript. أزرار الانتقاء radio عندما تكون جميع الأزرار التي لها نفس القيمة للخاصية name غير منتقاةً. عناصر <progress> في الحالة غير المعروفة. الشكل العام لهذا المحدد: :indeterminate
أمثلة سنُطبِّق في المثال الآتي أنماط خاصة لعناصر <label> المرتبطة بحقول النموذج ذات الحالة غير المعروفة: ...
تقديم الكائن الفارغ (Introduce Null Object)
المشكلة تؤدي إعادة بعض التوابع للقيمة null بدلًا من الكائنات الحقيقية إلى امتلاء الشيفرة البرمجية بالعديد من نقاط التحقق من القيمة null. الحل إعادة كائن فارغ يظهر السلوك الافتراضي بدلًا من null. مثال قبل إعادة التصميم وجودة نقطة تحقق شرطية من الكائن customer لاتخاذ إجراء مناسب إن كانت قيمته null: في لغة Java: if (customer == null) {
plan = BillingPlan.basic();
}
else {
plan = customer.getPlan();
}
في لغة C#: if (customer == null)
{
plan = BillingPlan.Basic();
}
else
{
...
تغليف المجموعات (Encapsulate Collection)
المشكلة صنف يحتوي على حقل مجموعة وجالب (getter) وضابط (setter) بسيط للعمل مع المجموعة. الحل ضبط القيمة المعادة من الجالب لتكون للقراءة فقط وإنشاء توابع لإضافة/حذف عناصر المجموعة. مثال قبل إعادة التصميم يحتوي الصنف Person على جالب getCourses وضابط setCourses بسيطين للتحكم بالدروس التي سجل بها الشخص: صنف يحتوي على حقل مجموعة وجالب (getter) وضابط (setter) بسيط للعمل مع المجموعة. بعد إعادة التصميم ضبط القيمة المعادة من الجالب setCourses لتصبح للقراءة فقط وإضافة تابعين جديدين أحدهما لإضافة دروس جديدة للشخص ...
تبديل الشرطيات المتداخلة بعبارات الحماية (Replace Nested Conditional with Guard Clauses
المشكلة وجود مجموعة متداخلة من الشروط وصعوبة تحديد التدفق الطبيعي لتنفيذ الشيفرة البرمجية. الحل عزل جميع الاختبارات الخاصة والحالات الطرفية في عبارات منفصلة ووضعها قبل الاختبارات الرئيسية. من الناحية المثالية، يجب أن يكون لديك قائمة "مسطحة" من الشروط، واحدةً تلو الأخرى. مثال قبل إعادة التصميم يوجد لدينا الدالة ()getPayAmount التي تتحقق من القيمة المُستدعاة معها عبر عدد من الشروط المتشعبة - مع استعمال المتغير result للحصول على النتيجة وإعادتها في النهاية - مما يجعل معرفة تدفق ومسار الدالة أمرًا معقدًا: ...
عرض (250 السابقة | 250 التالية) (20 | 50 | 100 | 250 | 500).