الفرق بين المراجعتين لصفحة: «Refactoring/split temporary variable»

من موسوعة حسوب
إنشاء الصفحة. هذه الصفحة من مساهمات "نور تامر".
 
ط مراجعة وتدقيق.
سطر 9: سطر 9:


=== قبل إعادة التصميم ===
=== قبل إعادة التصميم ===
نلاحظ في الشيفرة الآتية استخدام المتغيِّر <code>temp</code> لتخزين ناتج كلِّ من تعبيريّ المحيط والمساحة:<syntaxhighlight lang="java">
نلاحظ في الشيفرة الآتية استخدام المتغيِّر <code>temp</code> لتخزين ناتج كلِّ من تعبيريّ المحيط والمساحة:
 
في لغة Java:<syntaxhighlight lang="java">
double temp = 2 * (height + width);
double temp = 2 * (height + width);
System.out.println(temp);
System.out.println(temp);
سطر 15: سطر 17:
System.out.println(temp);
System.out.println(temp);


</syntaxhighlight>في لغة #C:<syntaxhighlight lang="c#">
double temp = 2 * (height + width);
Console.WriteLine(temp);
temp = height * width;
Console.WriteLine(temp);
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php">
$temp = 2 * ($this->height + $this->width);
echo $temp;
$temp = $this->height * $this->width;
echo $temp;
</syntaxhighlight>في لغة Python:<syntaxhighlight lang="python">
temp = 2 * (height + width)
print(temp)
temp = height * width
print(temp)
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript">
let temp = 2 * (height + width);
console.log(temp);
temp = height * width;
console.log(temp);
</syntaxhighlight>
</syntaxhighlight>
=== بعد إعادة التصميم ===
يُخصَّص متغيران منفصلان للمحيط (باسم <code>perimeter</code>) والمساحة (باسم <code>area</code>) لتصبح الشيفرة بالشكل:


=== بعد إعادة التصميم ===
في لغة Java:<syntaxhighlight lang="java">
يُخصَّص متغيران منفصلان للمحيط (باسم <code>perimeter</code>) والمساحة (باسم <code>area</code>) لتصبح الشيفرة بالشكل:<syntaxhighlight lang="java">
final double perimeter = 2 * (height + width);
final double perimeter = 2 * (height + width);
System.out.println(perimeter);
System.out.println(perimeter);
سطر 24: سطر 47:
System.out.println(area);
System.out.println(area);


</syntaxhighlight>في لغة #C:<syntaxhighlight lang="c#">
readonly double perimeter = 2 * (height + width);
Console.WriteLine(perimeter);
readonly double area = height * width;
Console.WriteLine(area);
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php">
$perimeter = 2 * ($this->height + $this->width);
echo $perimeter;
$area = $this->height * $this->width;
echo $area;
</syntaxhighlight>في لغة Python:<syntaxhighlight lang="python">
perimeter = 2 * (height + width)
print(perimeter);
area = height * width
print(area)
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript">
const perimeter = 2 * (height + width);
console.log(perimeter);
const area = height * width;
console.log(area);
</syntaxhighlight>
</syntaxhighlight>
== لم إعادة التصميم؟ ==
== لم إعادة التصميم؟ ==
عند إعادة استخدامك لنفس المتغيِّر في الدالة (function) أو التابع (method) بهدف التقليل من عدد المتغيِّرات الإجماليّ في البرنامج فمن المُتوقَّع أن تواجه بعض المشاكل عند إجرائِك أيَّ تغييرٍ لاحقٍ في الشيفرة التي تستخدم ذلك المتغيِّر، وعليك حينئذٍ التحقُّق مجددًا من كلِّ حالةٍ استُخدم فيها المتغيِّر وذلك لضمان احتوائه على القيمة الصحيحة المطلوبة.
عند إعادة استخدامك لنفس المتغيِّر في الدالة (function) أو التابع (method) بهدف التقليل من عدد المتغيِّرات الإجماليّ في البرنامج فمن المُتوقَّع أن تواجه بعض المشاكل عند إجرائِك أيَّ تغييرٍ لاحقٍ في الشيفرة التي تستخدم ذلك المتغيِّر، وعليك حينئذٍ التحقُّق مجددًا من كلِّ حالةٍ استُخدم فيها المتغيِّر وذلك لضمان احتوائه على القيمة الصحيحة المطلوبة.
سطر 32: سطر 74:
* سيصبح كل جزءٍ من شيفرة البرنامج مسؤولًا عن مهمةٍ واحدةٍ (وواحدةٍ فقط) مما يجعل من السهل صيانة (maintenance) البرنامج إذ من الممكن القيام بأيّ تبديلٍ دون القلق حيال الآثار الجانبية التي قد تنجم عن هذا التبديل.
* سيصبح كل جزءٍ من شيفرة البرنامج مسؤولًا عن مهمةٍ واحدةٍ (وواحدةٍ فقط) مما يجعل من السهل صيانة (maintenance) البرنامج إذ من الممكن القيام بأيّ تبديلٍ دون القلق حيال الآثار الجانبية التي قد تنجم عن هذا التبديل.
* ستصبح الشيفرة مقروءةً أكثر، فإن كان الإنشاء السابق للمتغيِّر على عجالةٍ فلربما تشابه تسميته إحدى التسميات: <code>k</code> أو <code>a2</code> أو <code>value</code> أو...إلخ. ولكن من السهل إعادة تسمية المتغيِّرات لتصبح بأسماءٍ واضحةٍ سهلة الفهم مثل: <code>customerTaxValue</code> أو <code>cityUnemploymentRate</code> أو <code>clientSalutationString</code> أو ما يماثلها.
* ستصبح الشيفرة مقروءةً أكثر، فإن كان الإنشاء السابق للمتغيِّر على عجالةٍ فلربما تشابه تسميته إحدى التسميات: <code>k</code> أو <code>a2</code> أو <code>value</code> أو...إلخ. ولكن من السهل إعادة تسمية المتغيِّرات لتصبح بأسماءٍ واضحةٍ سهلة الفهم مثل: <code>customerTaxValue</code> أو <code>cityUnemploymentRate</code> أو <code>clientSalutationString</code> أو ما يماثلها.
* تفيد تقنية الحلِّ هذه عندما يُتوقَع تطبيق تقنية الحل باستخراج التابع (extract method) فيما بعد.
* تفيد تقنية الحلِّ هذه عندما يُتوقَع تطبيق تقنية الحل [[Refactoring/extract method|باستخراج التابع]] (extract method) فيما بعد.


== آلية الحل ==
== آلية الحل ==
سطر 46: سطر 88:
== مصادر ==
== مصادر ==
* [https://refactoring.guru/split-temporary-variable صفحة توثيق تجزئة المتغيِّر المؤقّت في موقع refactoring.guru.]
* [https://refactoring.guru/split-temporary-variable صفحة توثيق تجزئة المتغيِّر المؤقّت في موقع refactoring.guru.]
[[تصنيف: Refactoring]]
[[تصنيف:Refactoring]]
[[تصنيف:Refactoring Techniques]]
[[تصنيف:Refactoring Composing Methods]]

مراجعة 08:22، 2 مارس 2019

المشكلة

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

الحل

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

مثال

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

نلاحظ في الشيفرة الآتية استخدام المتغيِّر 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. تكرار الخطوتين السابقتين لكلِّ عملية إسنادٍ للمتغيِّر.

انظر أيضًا

مصادر