الفرق بين المراجعتين لصفحة: «Refactoring/replace magic number with symbolic constant»

من موسوعة حسوب
طلا ملخص تعديل
ط مراجعة
 
سطر 8: سطر 8:


==== قبل إعادة التصميم ====
==== قبل إعادة التصميم ====
تستخدم الشيفرة التالية العدد 9.81 بالشكل المجرَّد الذي يمثِّل ثابت الجاذبية الأرضية:
في لغة Java:<syntaxhighlight lang="java">
في لغة Java:<syntaxhighlight lang="java">
double potentialEnergy(double mass, double height) {
double potentialEnergy(double mass, double height) {
سطر 24: سطر 26:
def potentialEnergy(mass, height):
def potentialEnergy(mass, height):
     return mass * height * 9.81
     return mass * height * 9.81
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript">
potentialEnergy(mass: number, height: number): number {
  return mass * height * 9.81;
}
</syntaxhighlight>
</syntaxhighlight>


==== بعد إعادة التصميم ====
==== بعد إعادة التصميم ====
التصريح عن ثابت عددي باسم <code>GRAVITATIONAL_CONSTANT</code> يحوي تلك القيمة:
في لغة Java:<syntaxhighlight lang="java">
في لغة Java:<syntaxhighlight lang="java">
static final double GRAVITATIONAL_CONSTANT = 9.81;
static final double GRAVITATIONAL_CONSTANT = 9.81;
سطر 51: سطر 59:
def potentialEnergy(mass, height):
def potentialEnergy(mass, height):
     return mass * height * GRAVITATIONAL_CONSTANT
     return mass * height * GRAVITATIONAL_CONSTANT
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript">
static const GRAVITATIONAL_CONSTANT = 9.81;
potentialEnergy(mass: number, height: number): number {
  return mass * height * GRAVITATIONAL_CONSTANT;
}
</syntaxhighlight>
</syntaxhighlight>


سطر 71: سطر 85:
== البدائل ==
== البدائل ==
# في بعض الأحيان، يمكن استبدال العدد السحري باستدعاءات التابع. على سبيل المثال، إذا كان لديك عدد سحري يدل على عدد العناصر في مجموعة، فإنك لن تحتاج إلى استخدامه للتحقق من العنصر الأخير من المجموعة. وبدلًا من ذلك، يُستخدم التابع القياسي للحصول على طول المجموعة.
# في بعض الأحيان، يمكن استبدال العدد السحري باستدعاءات التابع. على سبيل المثال، إذا كان لديك عدد سحري يدل على عدد العناصر في مجموعة، فإنك لن تحتاج إلى استخدامه للتحقق من العنصر الأخير من المجموعة. وبدلًا من ذلك، يُستخدم التابع القياسي للحصول على طول المجموعة.
# تُستخدم الأعداد السحرية أحيانُا كرموز للأنواع. لنفترض أنَّ لديك نوعين من المستخدمين وأنك تستخدم حقل عددي في صنف لتحديد كِلاهما: فيكون العدد <code>1</code> للمسؤولين والعدد <code>2</code> للمستخدمين العاديين. في هذه الحالة، يجب استخدام أحد توابع إعادة التصميم لتجنب رموز الأنواع: '''-'''  [[Refactoring/replace type code with class|تبديل رموز الأنواع بالأصناف]].  '''-'''  [[Refactoring/replace type code with subclasses|تبديل رموز الأنواع بالأصناف الفرعية]].  '''-'''  [[Refactoring/replace type code with state strategy|تبديل رموز الأنواع بالحالة/الاستراتيجية]].
# تُستخدم الأعداد السحرية أحيانُا كرموز للأنواع. لنفترض أنَّ لديك نوعين من المستخدمين وأنك تستخدم حقل عددي في صنف لتحديد كِلاهما: فيكون العدد <code>1</code> للمسؤولين والعدد <code>2</code> للمستخدمين العاديين. في هذه الحالة، يجب استخدام أحد توابع إعادة التصميم لتجنب رموز الأنواع:
#* [[Refactoring/replace type code with class|تبديل رموز الأنواع بالأصناف]]
#* [[Refactoring/replace type code with subclasses|تبديل رموز الأنواع بالأصناف الفرعية]]
#* [[Refactoring/replace type code with state strategy|تبديل رموز الأنواع بالحالة/الاستراتيجية]]
== آلية الحل ==
== آلية الحل ==
# عرِّف ثابتًا وعيّن له قيمة العدد السحري.
# عرِّف ثابتًا وعيّن له قيمة العدد السحري.
سطر 83: سطر 100:


== مصادر ==
== مصادر ==
* [https://refactoring.guru/replace-magic-number-with-symbolic-constant صفحة توثيق تبديل الأعداد السحرية بثوابت رمزية في موقع refactoring.guru].   [[تصنيف:Refactoring]]   [[تصنيف:Refactoring Techniques]]   [[تصنيف:Refactoring Organizing Data]]
* [https://refactoring.guru/replace-magic-number-with-symbolic-constant صفحة توثيق تبديل الأعداد السحرية بثوابت رمزية في موقع refactoring.guru].   [[تصنيف:Refactoring]]   [[تصنيف:Refactoring Techniques]]   [[تصنيف:Refactoring Organizing Data]]

المراجعة الحالية بتاريخ 11:25، 2 مارس 2019

المشكلة

تستخدم الشيفرة البرمجية عددًا له معنىً معين له.

الحل

استبدال هذا العدد بثابت له اسم يمكن قراءته ويشرح معنى العدد.

مثال

قبل إعادة التصميم

تستخدم الشيفرة التالية العدد 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 * 9.81;
}

في لغة Python:

def potentialEnergy(mass, height):
    return mass * height * 9.81

في لغة TypeScript:

potentialEnergy(mass: number, height: number): number {
  return mass * height * 9.81;
}

بعد إعادة التصميم

التصريح عن ثابت عددي باسم GRAVITATIONAL_CONSTANT يحوي تلك القيمة:

في لغة Java:

static final double GRAVITATIONAL_CONSTANT = 9.81;

double potentialEnergy(double mass, double height) {
  return mass * height * GRAVITATIONAL_CONSTANT;
}

في لغة C#‎:

const double GRAVITATIONAL_CONSTANT = 9.81;

double PotentialEnergy(double mass, double height) 
{
  return mass * height * GRAVITATIONAL_CONSTANT;
}

في لغة PHP:

define("GRAVITATIONAL_CONSTANT", 9.81);

function potentialEnergy($mass, $height) {
  return $mass * $height * GRAVITATIONAL_CONSTANT;
}

في لغة Python:

GRAVITATIONAL_CONSTANT = 9.81

def potentialEnergy(mass, height):
    return mass * height * GRAVITATIONAL_CONSTANT

في لغة TypeScript:

static const GRAVITATIONAL_CONSTANT = 9.81;

potentialEnergy(mass: number, height: number): number {
  return mass * height * GRAVITATIONAL_CONSTANT;
}

لم إعادة التصميم؟

العدد السحري هو القيمة العددية التي تتصادف في المصدر ولكن ليس لها معنىً واضح. ويجعل هذا "النمط المضاد" فهم البرنامج وإعادة تصميم الشيفرة البرمجية أمرًا صعبًا.

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

فوائد تطبيق الحل

  • يمكن أن يخدم الثابت الرمزي كتوثيق حي لمعنى قيمته.
  • من الأسهل بكثير تغيير قيمة ثابتٍ ما عن البحث عن هذا العدد في مصدر الشيفرة البرمجية بأكمله، دون خطر تغيير نفس العدد المستخدم في مكان آخر لغرض مختلف بطريق الخطأ.
  • تقليل الاستخدام المُكرَر لعدد أو سلسلة نصية في الشيفرة البرمجية. وهو مهم بشكل خاص عندما تكون القيمة معقدة وطويلة (مثل 3.14159 أو 0xCAFEBABE).

من الجيد أن نعرف

ليس كل الأعداد سحرية. إذا كان الغرض من العدد واضحًا، فلا حاجة إلى استبداله. والمثال الكلاسيكي هو:

for (i = 0; i < сount; i++) { ... }

البدائل

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

آلية الحل

  1. عرِّف ثابتًا وعيّن له قيمة العدد السحري.
  2. ابحث عن كل إِشارة للعدد السحري.
  3. لكل من الأعداد التي تجدها، تحقق مرتين من أن العدد السحري في هذه الحالة بالذات يتوافق مع الغرض من الثابت. إذا كان الجواب نعم، استبدل العدد بالثابت. هذه خطوة مهمة بما أن العدد نفسه قد يعني أشياء مختلفة تمامًا (ويستبدل مع ثوابت مختلفة بحسب الحالة).

انظر أيضًا

مصادر