الفرق بين المراجعتين ل"Refactoring/move method"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(إنشاء الصفحة. هذه الصفحة من مساهمات "نور تامر".)
 
(مراجعة وتدقيق.)
 
سطر 9: سطر 9:
  
 
==== قبل إعادة التصميم ====
 
==== قبل إعادة التصميم ====
يستخدِم الصنفُ <code>Class2</code> في الشيفرة الآتية التابعَ <code>aMethod()</code>‎ أكثر مما يستخدمه صنفه الأساسيّ <code>Class1</code>:<syntaxhighlight lang="java">
+
يستخدِم الصنفُ <code>Class2</code> التابعَ <code>aMethod()</code>‎ أكثر مما يستخدمه صنفه الأساسيّ <code>Class1</code>:
class Class1 {
 
  //...
 
  public double aMethod() {
 
    //...
 
  }
 
}
 
class Class2 {
 
    // استخدام متكرر للتابع في الصنف السابق
 
  }
 
}
 
 
 
</syntaxhighlight>
 
  
 +
[[ملف:Move_Method_-_Before.png|بديل=يستخدِم الصنفُ <code>Class2</code> التابعَ <code>aMethod()</code>‎ أكثر مما يستخدمه صنفه الأساسيّ <code>Class1</code>.|بدون|تصغير|180بك|يستخدِم الصنفُ <code>Class2</code> التابعَ <code>aMethod()</code>‎ أكثر مما يستخدمه صنفه الأساسيّ <code>Class1</code>.]]
 
==== بعد إعادة التصميم ====
 
==== بعد إعادة التصميم ====
نُقِل التابع <code>aMethod()</code>‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف <code>Class2</code>:<syntaxhighlight lang="java">
+
نُقِل التابع <code>aMethod()</code>‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف <code>Class2</code>:
class Class1 {
 
  //...
 
}
 
class Class2 {
 
  public double aMethod() {
 
    // أصبح التابع في الصنف الذي يستخدمه أكثر
 
  }
 
}
 
 
 
</syntaxhighlight>
 
  
 +
[[ملف:Move_Method_-_After.png|بديل=نُقِل التابع <code>aMethod()</code>‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف <code>Class2</code>.|بدون|تصغير|180بك|نُقِل التابع <code>aMethod()</code>‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف <code>Class2</code>.]]
 
== لم إعادة التصميم؟ ==
 
== لم إعادة التصميم؟ ==
 
# لجعل الأصناف (classes) أكثر ترابطًا على المستوى الداخلي، وذلك بنقل التابع إلى الصنف الذي يحتوي معظم البيانات التي يحتاجها.
 
# لجعل الأصناف (classes) أكثر ترابطًا على المستوى الداخلي، وذلك بنقل التابع إلى الصنف الذي يحتوي معظم البيانات التي يحتاجها.
سطر 54: سطر 34:
 
* [https://refactoring.guru/replace-method-with-method-object صفحة توثيق نقل التابع في موقع refactoring.guru.]
 
* [https://refactoring.guru/replace-method-with-method-object صفحة توثيق نقل التابع في موقع refactoring.guru.]
 
[[تصنيف:Refactoring]]
 
[[تصنيف:Refactoring]]
 +
[[تصنيف:Refactoring Techniques]]
 +
[[تصنيف:Refactoring Moving Features between Objects]]

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

المشكلة

استخدام التابع (method) في صنفٍ (class) ما أكثر من استخدامه في صنفه الأساسيّ.

الحل

إنشاء تابعٍ جديدٍ في الصنف الأكثر استخدامًا لذلك التابع ونقل شيفرته إلى التابع الجديد، ثم تحويل الشيفرة في التابع الأصليّ إلى مرجعيّةٍ للتابع الجديد في الصنف الآخر أو حذفه كليَّا.

مثال

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

يستخدِم الصنفُ Class2 التابعَ aMethod()‎ أكثر مما يستخدمه صنفه الأساسيّ Class1:

يستخدِم الصنفُ Class2 التابعَ aMethod()‎ أكثر مما يستخدمه صنفه الأساسيّ Class1.
يستخدِم الصنفُ Class2 التابعَ aMethod()‎ أكثر مما يستخدمه صنفه الأساسيّ Class1.

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

نُقِل التابع aMethod()‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف Class2:

نُقِل التابع aMethod()‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف Class2.
نُقِل التابع aMethod()‎ إلى الصنف ذي الاستخدام الأكثر له وهو الصنف Class2.

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

  1. لجعل الأصناف (classes) أكثر ترابطًا على المستوى الداخلي، وذلك بنقل التابع إلى الصنف الذي يحتوي معظم البيانات التي يحتاجها.
  2. الحدُّ من الاعتماديّة (dependency) ما بين الأصناف أو التخليّ عنها، والمقصود بالاعتماديّة هو اعتماد الصنف الذي يستدعي التابع على الصنف الذي يحتوي ذلك التابع، ويبدو ذلك مفيدًا بشكلٍ خاصّ عندما يكون الصنف الذي يستدعي التابع معتمدًا بالأصل (قبل إعادة التصميم) على الصنف الذي نُقل إليه التابع.

آلية الحل

  1. إعادة النظر بكلِّ الميّزات (features) التي يستخدمها التابع (method) في صنفه الأصليّ، فقد يكون من الأفضل نقلها كذلك، ولتكن القاعدة: تُنقَل الميّزات إلى التابع إن كانت غير مُستخدَمةٍ إلا من قِبله، أمّا بوجود توابع أخرى تستخدم تلك الميّزة فمن المهمّ نقلها أيضًا، إذ من الأسهل (في بعض الأحيان) نقلُ عددٍ كبيرٍ من التوابع بدلًا من تسوية العلاقات بينها عبر صنفين مختلفين. كما ويجب التأكُّد من أنّ التابع غير مصرَّحٍ عنه (not declared) في الأصناف الأعلى (superclasses) أو الأصناف الفرعيّة (subclasses)، وإلا فإمّا أن تتخلى عن فكرة النقل أو أن تلجأ إلى التعدديّةً الشكليّةً (polymorphism) في الصنف المستقبِل (recipient class) لضمان فعاليّة (functionality) التابع المتوزِّع في عدَّة أصناف.
  2. التصريح عن التابع الجديد في الصنف المستقبِل (recipient class) وقد يُعطى اسمًا جديدًا معبِّرًا أكثر من الاسم السابق.
  3. توفير المرجعيّة إلى الصنف المستقبِل، فقد يكون هنالك بالأصل حقلٌ (field) أو تابعٌ (method) يعيد كائنًا (object) مناسبًا، وإن لم يكن ذلك فلا بُدَّ من إنشاء حقلٍ أو كتابة تابعٍ جديدٍ لتخزين كائن الصنف المستقبِل، وبهذا تضمن سهولة الوصول إلى الصنف المستقبِل والتابع الجديد فيه، وبقي تحويل التابع السابق إلى مرجعيّة (reference) لهذا التابع الجديد.
  4. التأكُّد من القدرة على حذف التابع السابق بأكمله، والإشارة بمرجعيّة إلى التابع الجديد في كافّة المواضع التي تستخدم التابع السابق.

انظر أيضًا

مصادر