الفرق بين المراجعتين ل"Refactoring/replace parameter with explicit methods"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE: استبدال المعامل بتوابع صريحة (Replace Parameter with Explicit Methods)}}</noinclude> == المشكلة == ينقسم...')
 
ط (مراجعة وتدقيق.)
 
سطر 9: سطر 9:
  
 
==== قبل إعادة التصميم ====
 
==== قبل إعادة التصميم ====
 +
وجود تابع يدعى <code>()setValue</code> يضبط قيمة الارتفاع والعرض بناءً على تمرير سلسلة نصية صريحة بذلك:
 +
 
في لغة Java:<syntaxhighlight lang="java">
 
في لغة Java:<syntaxhighlight lang="java">
 
void setValue(String name, int value) {
 
void setValue(String name, int value) {
سطر 59: سطر 61:
  
 
==== بعد إعادة التصميم ====
 
==== بعد إعادة التصميم ====
 +
استخراج التابع السابق إلى تابعين <code>()setHeight</code> و <code>()setWidth</code> يضبط الأول قيمة الارتفاع والثاني قيمة العرض:
 +
 
في لغة Java:<syntaxhighlight lang="java">
 
في لغة Java:<syntaxhighlight lang="java">
 
void setHeight(int arg) {
 
void setHeight(int arg) {
سطر 93: سطر 97:
  
 
== لم إعادة التصميم؟ ==
 
== لم إعادة التصميم؟ ==
تضخم التابع الذي يحتوي على بدائل تعتمد على المعامل بشكل هائل. تُشغَّل الشيفرة غير التافهة في كل فرع ونادرًا جدًا ما تضاف بدائل جديدة.
+
يعتمد تضخُّم التابع الذي يحتوي على بدائل على المعامل بشكل هائل. تُشغَّل الشيفرة غير التافهة في كل فرع ونادرًا جدًا ما تضاف بدائل جديدة.
  
 
== فوائد تطبيق الحل ==
 
== فوائد تطبيق الحل ==
 
* تحسين إمكانية قراءة الشيفرة البرمجية. فإنه من الأسهل بكثير فهم الغرض من <code>startEngine()</code>‎ عن <code>setValue("engineEnabled", true)‎</code>.
 
* تحسين إمكانية قراءة الشيفرة البرمجية. فإنه من الأسهل بكثير فهم الغرض من <code>startEngine()</code>‎ عن <code>setValue("engineEnabled", true)‎</code>.
  
== متى يُترك هذا الحل؟ ==
+
== متى يترك هذا الحل؟ ==
 
* لا يُستبدل المعامل بتوابع صريحة إذا كان من النادر تغيير التابع ولا تُضاف بدائل جديدة داخله.
 
* لا يُستبدل المعامل بتوابع صريحة إذا كان من النادر تغيير التابع ولا تُضاف بدائل جديدة داخله.
  
 
== آلية الحل ==
 
== آلية الحل ==
# أنشئ تابع منفصل لكل بديل لهذا التابع. شغِّل هذه التوابع بناء على قيمة المعامل في التابع الرئيسي.
+
# أنشئ تابعًا منفصلًا لكل بديل لهذا التابع. شغِّل هذه التوابع بناءً على قيمة المعامل في التابع الرئيسي.
# ابحث عن كل الأماكن التي يُستدعى فيها التابع الأصلي. ضع في هذه الأماكن استدعاء لأحد البدائل الجديدة المعتمدة على المعامل.
+
# ابحث عن كل الأماكن التي يُستدعى فيها التابع الأصلي. ضع في هذه الأماكن استدعاءً لأحد البدائل الجديدة المعتمدة على المعامل.
 
# عندما لا يتبقى أية استدعاءات إلى التابع الأصلي، احذفه.
 
# عندما لا يتبقى أية استدعاءات إلى التابع الأصلي، احذفه.
  
سطر 116: سطر 120:
 
[[تصنيف:Refactoring]]
 
[[تصنيف:Refactoring]]
 
[[تصنيف:Refactoring Techniques]]
 
[[تصنيف:Refactoring Techniques]]
[[تصنيف:Simplifying Method Calls]]
+
[[تصنيف:Refactoring Simplifying Method Calls]]

المراجعة الحالية بتاريخ 07:22، 26 فبراير 2019

المشكلة

ينقسم التابع إلى أجزاء، كل منها يتم تشغيله اعتمادًا على قيمة المعامل.

الحل

استخراج الأجزاء الفردية من التابع إلى توابعها الخاصة واستدعائها بدلًا من استدعاء التابع الأصلي.

مثال

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

وجود تابع يدعى ()setValue يضبط قيمة الارتفاع والعرض بناءً على تمرير سلسلة نصية صريحة بذلك:

في لغة Java:

void setValue(String name, int value) {
  if (name.equals("height")) {
    height = value;
    return;
  }
  if (name.equals("width")) {
    width = value;
    return;
  }
  Assert.shouldNeverReachHere();
}

في لغة C#‎:

void SetValue(string name, int value) 
{
  if (name.Equals("height")) 
  {
    height = value;
    return;
  }
  if (name.Equals("width")) 
  {
    width = value;
    return;
  }
  Assert.Fail();
}

في لغة PHP:

function setValue($name, $value) {
  if ($name === "height") {
    $this->height = $value;
    return;
  }
  if ($name === "width") {
    $this->width = $value;
    return;
  }
  assert("Should never reach here");
}

في لغة Python:

def output(self, type):
    if name == "banner"
        # Print the banner.
        # ...
    if name == "info"
        # Print the info.
        # ...

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

استخراج التابع السابق إلى تابعين ()setHeight و ()setWidth يضبط الأول قيمة الارتفاع والثاني قيمة العرض:

في لغة Java:

void setHeight(int arg) {
  height = arg;
}
void setWidth(int arg) {
  width = arg;
}

في لغة C#‎:

void SetHeight(int arg) 
{
  height = arg;
}
void SetWidth(int arg) 
{
  width = arg;
}

في لغة PHP:

function setHeight($arg) {
  $this->height = $arg;
}
function setWidth($arg) {
  $this->width = $arg;
}

في لغة Python:

def outputBanner(self):
    # Print the banner.
    # ...

def outputInfo(self):
    # Print the info.
    # ...

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

يعتمد تضخُّم التابع الذي يحتوي على بدائل على المعامل بشكل هائل. تُشغَّل الشيفرة غير التافهة في كل فرع ونادرًا جدًا ما تضاف بدائل جديدة.

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

  • تحسين إمكانية قراءة الشيفرة البرمجية. فإنه من الأسهل بكثير فهم الغرض من startEngine()‎ عن setValue("engineEnabled", true)‎.

متى يترك هذا الحل؟

  • لا يُستبدل المعامل بتوابع صريحة إذا كان من النادر تغيير التابع ولا تُضاف بدائل جديدة داخله.

آلية الحل

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

انظر أيضًا

مصادر