الفرق بين المراجعتين لصفحة: «Refactoring/inline method»
جميل-بيلوني (نقاش | مساهمات) إنشاء الصفحة. هذه الصفحة من مساهمات "نور تامر". |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة وتدقيق. |
||
(2 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:دمج التوابع ( | <noinclude>{{DISPLAYTITLE:دمج التوابع (Inline Methods)}}</noinclude> | ||
== المشكلة == | == المشكلة == | ||
أن يكون محتوى التابع (method body) بسيطًا وواضحًا أكثر من التابع بحدِّ ذاته، ويمكن عندئذٍ الاستغناء عنه. | أن يكون محتوى التابع (method body) بسيطًا وواضحًا أكثر من التابع بحدِّ ذاته، ويمكن عندئذٍ الاستغناء عنه. | ||
سطر 9: | سطر 9: | ||
=== قبل إعادة التصميم === | === قبل إعادة التصميم === | ||
نلاحظ أن محتوى التابع <code>moreThanFiveLateDeliveries()</code> واضحٌ وبسيطٌ لدرجةٍ تجعل الاستغناء عنه ممكنًا:<syntaxhighlight lang=" | نلاحظ أن محتوى التابع <code>moreThanFiveLateDeliveries()</code> واضحٌ وبسيطٌ لدرجةٍ تجعل الاستغناء عنه ممكنًا: | ||
في لغة Java:<syntaxhighlight lang="java"> | |||
class PizzaDelivery { | class PizzaDelivery { | ||
//... | //... | ||
سطر 20: | سطر 22: | ||
} | } | ||
</syntaxhighlight>في لغة #C:<syntaxhighlight lang="c#"> | |||
class PizzaDelivery | |||
{ | |||
// ... | |||
int GetRating() | |||
{ | |||
return MoreThanFiveLateDeliveries() ? 2 : 1; | |||
} | |||
bool MoreThanFiveLateDeliveries() | |||
{ | |||
return numberOfLateDeliveries > 5; | |||
} | |||
} | |||
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php"> | |||
function getRating() { | |||
return ($this->moreThanFiveLateDeliveries()) ? 2 : 1; | |||
} | |||
function moreThanFiveLateDeliveries() { | |||
return $this->numberOfLateDeliveries > 5; | |||
} | |||
</syntaxhighlight>في لغة Python:<syntaxhighlight lang="python"> | |||
class PizzaDelivery: | |||
# ... | |||
def getRating(self): | |||
return 2 if self.moreThanFiveLateDeliveries() else 1 | |||
def moreThanFiveLateDeliveries(self): | |||
return self.numberOfLateDeliveries > 5 | |||
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript"> | |||
class PizzaDelivery { | |||
// ... | |||
getRating(): number { | |||
return moreThanFiveLateDeliveries() ? 2 : 1; | |||
} | |||
moreThanFiveLateDeliveries(): boolean { | |||
return numberOfLateDeliveries > 5; | |||
} | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== بعد إعادة التصميم === | === بعد إعادة التصميم === | ||
سيُستبدَل استدعاءُ التابع ليحلَّ محتوى التابع محلَّه بالشكل:<syntaxhighlight lang=" | سيُستبدَل استدعاءُ التابع ليحلَّ محتوى التابع محلَّه بالشكل: | ||
في لغة Java:<syntaxhighlight lang="java"> | |||
class PizzaDelivery { | class PizzaDelivery { | ||
//... | //... | ||
سطر 31: | سطر 73: | ||
} | } | ||
</syntaxhighlight>في لغة #C:<syntaxhighlight lang="c#"> | |||
class PizzaDelivery | |||
{ | |||
// ... | |||
int GetRating() | |||
{ | |||
return numberOfLateDeliveries > 5 ? 2 : 1; | |||
} | |||
} | |||
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php"> | |||
function getRating() { | |||
return ($this->numberOfLateDeliveries > 5) ? 2 : 1; | |||
} | |||
</syntaxhighlight>في لغة Python:<syntaxhighlight lang="python"> | |||
class PizzaDelivery: | |||
# ... | |||
def getRating(self): | |||
return 2 if self.numberOfLateDeliveries > 5 else 1 | |||
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript"> | |||
class PizzaDelivery { | |||
// ... | |||
getRating(): number { | |||
return numberOfLateDeliveries > 5 ? 2 : 1; | |||
} | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
سطر 51: | سطر 118: | ||
== مصادر == | == مصادر == | ||
* [https://refactoring.guru/inline-method صفحة توثيق دمج التوابع في موقع refactoring.guru.] | * [https://refactoring.guru/inline-method صفحة توثيق دمج التوابع في موقع refactoring.guru.] | ||
[[تصنيف:Refactoring]] | |||
[[تصنيف:Refactoring Techniques]] | |||
[[تصنيف:Refactoring Composing Methods]] |
المراجعة الحالية بتاريخ 08:23، 2 مارس 2019
المشكلة
أن يكون محتوى التابع (method body) بسيطًا وواضحًا أكثر من التابع بحدِّ ذاته، ويمكن عندئذٍ الاستغناء عنه.
الحل
نقل الشيفرة الموجودة في التابع (محتوى التابع) إلى مواقع استدعائه، وحذف التابع برمته إذ لا داعي له.
مثال
قبل إعادة التصميم
نلاحظ أن محتوى التابع moreThanFiveLateDeliveries()
واضحٌ وبسيطٌ لدرجةٍ تجعل الاستغناء عنه ممكنًا:
في لغة Java:
class PizzaDelivery {
//...
int getRating() {
return moreThanFiveLateDeliveries() ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
return numberOfLateDeliveries > 5;
}
}
في لغة #C:
class PizzaDelivery
{
// ...
int GetRating()
{
return MoreThanFiveLateDeliveries() ? 2 : 1;
}
bool MoreThanFiveLateDeliveries()
{
return numberOfLateDeliveries > 5;
}
}
في لغة PHP:
function getRating() {
return ($this->moreThanFiveLateDeliveries()) ? 2 : 1;
}
function moreThanFiveLateDeliveries() {
return $this->numberOfLateDeliveries > 5;
}
في لغة Python:
class PizzaDelivery:
# ...
def getRating(self):
return 2 if self.moreThanFiveLateDeliveries() else 1
def moreThanFiveLateDeliveries(self):
return self.numberOfLateDeliveries > 5
في لغة TypeScript:
class PizzaDelivery {
// ...
getRating(): number {
return moreThanFiveLateDeliveries() ? 2 : 1;
}
moreThanFiveLateDeliveries(): boolean {
return numberOfLateDeliveries > 5;
}
}
بعد إعادة التصميم
سيُستبدَل استدعاءُ التابع ليحلَّ محتوى التابع محلَّه بالشكل:
في لغة Java:
class PizzaDelivery {
//...
int getRating() {
return numberOfLateDeliveries > 5 ? 2 : 1;
}
}
في لغة #C:
class PizzaDelivery
{
// ...
int GetRating()
{
return numberOfLateDeliveries > 5 ? 2 : 1;
}
}
في لغة PHP:
function getRating() {
return ($this->numberOfLateDeliveries > 5) ? 2 : 1;
}
في لغة Python:
class PizzaDelivery:
# ...
def getRating(self):
return 2 if self.numberOfLateDeliveries > 5 else 1
في لغة TypeScript:
class PizzaDelivery {
// ...
getRating(): number {
return numberOfLateDeliveries > 5 ? 2 : 1;
}
}
لم إعادة التصميم؟
عندما يُفضي (delegate) التابع إلى تابعٍ آخر فلا مشكلة بهذا المنطق بحدِّ ذاته، ولكن تنجم المشكلة عندما يكون هنالك الكثير من هذه التوابع غير المجدية، إذ لا تكون هذه التوابع قصيرةً بادئ الأمر، ولكنها تصبح كذلك بعد الكثير من التعديلات التي تطرأ على البرنامج، والأولى التخلُّص منها فهي بلا فائدة مرجوَّة.
فوائد تطبيق الحل
جعل الشيفرة أكثر وضوحًا بتقليل عدد التوابع غير المفيدة فيها.
آلية الحل
- التأكُّد من أنّ التابع لا يُعاد تعريفه في أيّ من الأصناف الفرعية (subclasses)، فإن كان مُعرَّفًا فعليك العزوف عن دمج التابع.
- إيجاد كافّة استدعاءات هذا التابع في الشيفرة وتبديلها إلى محتواه الفعليّ.
- حذف التابع.