الفرق بين المراجعتين ل"Refactoring/split temporary variable"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
ط (مراجعة وتدقيق.)
ط
 
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:تجزئة المتغير المؤقت (Split Temporary Variable)}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:تجزئة المتغير المؤقت (Split Temporary Variable)}}</noinclude>
 +
 
== المشكلة ==
 
== المشكلة ==
 
وجود متغيِّرٍ محليّ يُستخدَم لتخزين عدّة قيمٍ مؤقتةٍ (مرحليّة) داخل التابع.
 
وجود متغيِّرٍ محليّ يُستخدَم لتخزين عدّة قيمٍ مؤقتةٍ (مرحليّة) داخل التابع.
سطر 22: سطر 23:
 
temp = height * width;
 
temp = height * width;
 
Console.WriteLine(temp);
 
Console.WriteLine(temp);
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php">
+
</syntaxhighlight>في لغة [[PHP]]:<syntaxhighlight lang="php">
 
$temp = 2 * ($this->height + $this->width);
 
$temp = 2 * ($this->height + $this->width);
 
echo $temp;
 
echo $temp;

المراجعة الحالية بتاريخ 10:50، 7 أكتوبر 2022


المشكلة

وجود متغيِّرٍ محليّ يُستخدَم لتخزين عدّة قيمٍ مؤقتةٍ (مرحليّة) داخل التابع.

الحل

استخدام متغيِّراتٍ منفصلةٍ ومستقلّةٍ للقيم المختلفة، بحيث يكون كلَُ متغيِّرٍ مسؤولًا عن تخزين البيانات لمهمةٍ واحدةٍ فقط.

مثال

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

نلاحظ في الشيفرة الآتية استخدام المتغيِّر 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 = 2 * ($this->height + $this->width);
echo $temp;
$temp = $this->height * $this->width;
echo $temp;

في لغة Python:

temp = 2 * (height + width)
print(temp)
temp = height * width
print(temp)

في لغة TypeScript:

let temp = 2 * (height + width);
console.log(temp);
temp = height * width;
console.log(temp);

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

يُخصَّص متغيران منفصلان للمحيط (باسم perimeter) والمساحة (باسم area) لتصبح الشيفرة بالشكل:

في لغة Java:

final double perimeter = 2 * (height + width);
System.out.println(perimeter);
final double area = height * width;
System.out.println(area);

في لغة #C:

readonly double perimeter = 2 * (height + width);
Console.WriteLine(perimeter);
readonly double area = height * width;
Console.WriteLine(area);

في لغة PHP:

$perimeter = 2 * ($this->height + $this->width);
echo $perimeter;
$area = $this->height * $this->width;
echo $area;

في لغة Python:

perimeter = 2 * (height + width)
print(perimeter);
area = height * width
print(area)

في لغة TypeScript:

const perimeter = 2 * (height + width);
console.log(perimeter);
const area = height * width;
console.log(area);

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

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

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

  • سيصبح كل جزءٍ من شيفرة البرنامج مسؤولًا عن مهمةٍ واحدةٍ (وواحدةٍ فقط) مما يجعل من السهل صيانة (maintenance) البرنامج إذ من الممكن القيام بأيّ تبديلٍ دون القلق حيال الآثار الجانبية التي قد تنجم عن هذا التبديل.
  • ستصبح الشيفرة مقروءةً أكثر، فإن كان الإنشاء السابق للمتغيِّر على عجالةٍ فلربما تشابه تسميته إحدى التسميات: k أو a2 أو value أو...إلخ. ولكن من السهل إعادة تسمية المتغيِّرات لتصبح بأسماءٍ واضحةٍ سهلة الفهم مثل: customerTaxValue أو cityUnemploymentRate أو clientSalutationString أو ما يماثلها.
  • تفيد تقنية الحلِّ هذه عندما يُتوقَع تطبيق تقنية الحل باستخراج التابع (extract method) فيما بعد.

آلية الحل

  1. إيجاد أول عملية إسنادٍ للمتغيِّر وإعادة تسميته هناك إلى اسمٍ متناسبٍ مع القيمة المُسنَدة.
  2. استخدام التسمية الجديدة للمتغيِّر بدلًا من التسمية السابقة في كلِّ موضعٍ متعلِّق باستخدام تلك القيمة التي يحتويها.
  3. تكرار الخطوتين السابقتين لكلِّ عملية إسنادٍ للمتغيِّر.

انظر أيضًا

مصادر