الفرق بين المراجعتين لصفحة: «Refactoring/separate query from modifier»
Khaled-yassin (نقاش | مساهمات) طلا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة وتدقيق. |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: فصل الاستعلامات عن المُعدِّلات (Separate Query from Modifier)}}</noinclude> | <noinclude>{{DISPLAYTITLE: فصل الاستعلامات عن المُعدِّلات (Separate Query from Modifier)}}</noinclude> | ||
== المشكلة == | == المشكلة == | ||
هل لديك | هل لديك تابعٌ يُعيد قيمةً ما ولكن يغيِّر أيضا شيئًا ما داخل الكائن؟ | ||
== الحل == | == الحل == | ||
سطر 9: | سطر 9: | ||
==== قبل إعادة التصميم ==== | ==== قبل إعادة التصميم ==== | ||
[[ملف:Separate Query from Modifier - Before.png|بديل=تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن.|بدون|تصغير|تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن.]] | ينفذ التابع <code>()getTotlaOutstandingAndSetReadyForSummaries</code> في الصنف <code>Customer</code> مهمتين، إذ يعيد قيمة ويضبط قيمة أخرى في الكائن:[[ملف:Separate Query from Modifier - Before.png|بديل=تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن.|بدون|تصغير|تابع يُعيد قيمة ويغيِّر شيئًا ما داخل الكائن.]] | ||
==== بعد إعادة التصميم ==== | ==== بعد إعادة التصميم ==== | ||
[[ملف:Separate Query from Modifier - After.png|بديل=يقسَّم التابع إلى تابعَين منفصلَين.|بدون|تصغير|يقسَّم التابع إلى تابعَين منفصلَين.]] | فصل التابع التابع <code>()getTotlaOutstandingAndSetReadyForSummaries</code> إلى تابعين هما: الأول <code>()getTotlaOutstanding</code> لجلب قيمة، والآخر <code>()setReadyForSummaries</code> لضبط حالةٍ في الكائن:[[ملف:Separate Query from Modifier - After.png|بديل=يقسَّم التابع إلى تابعَين منفصلَين.|بدون|تصغير|يقسَّم التابع إلى تابعَين منفصلَين.]] | ||
== لم إعادة التصميم؟ == | == لم إعادة التصميم؟ == | ||
تفصل تقنية إعادة التصميم هذه مسؤولية الأوامر عن الاستعلامات (Command and Query Responsibility Segregation). ويدعو هذا المبدأ إلى فصل شيفرة الحصول على البيانات عن الشيفرة التي تغير شيئًا داخل الكائن. | تفصل تقنية إعادة التصميم هذه مسؤولية الأوامر عن الاستعلامات (Command and Query Responsibility Segregation). ويدعو هذا المبدأ إلى فصل شيفرة الحصول على البيانات عن الشيفرة التي تغير شيئًا داخل الكائن. | ||
وتسمَّى شيفرة | وتسمَّى شيفرة التي تجلب بيانات "استعلام" (query). وتسمَّى شيفرة التي تغير الأشياء في الحالة المرئية (visible state) للكائن "مُعدِّل" (modifier). عند الجمع بين الاستعلام والمُعدِّل، لن يكون لديك سبيل للحصول على البيانات دون إجراء تغييرات على حالتها. وبعبارة أخرى، يمكنك أن تطرح السؤال وتغير الإجابة حتى أثناء تلقيها. وتزداد هذه المشكلة حدةً عندما لا يعرف الشخص الذي يستدعي الاستعلام عن "الآثار الجانبية" للتابع، التي كثيرًا ما تؤدي إلى أخطاء وقت التشغيل. | ||
ولكن تذكَّر | ولكن تذكَّر أنَّ الآثار الجانبية لا تكون خطيرة إلا في حالة المُعدِّلات التي تغير الحالة المرئية للكائن. على سبيل المثال، يمكن الوصول إلى هذه الحقول من الواجهة العامة لكائن، أو عنصر في قاعدة بيانات، أو في الملفات وما إلى ذلك. إذا كان المُعدِّل يُخزِّن فقط عملية معقدة ويحفظها داخل الحقل الخاص لصنف ما، فإنه بالكاد قد يسبب آثارًا جانبية. | ||
== فوائد تطبيق الحل == | == فوائد تطبيق الحل == | ||
سطر 25: | سطر 25: | ||
== مساوئ تطبيق الحل == | == مساوئ تطبيق الحل == | ||
* في بعض الحالات يكون من الملائم الحصول على البيانات بعد تنفيذ | * في بعض الحالات يكون من الملائم الحصول على البيانات بعد تنفيذ أمر. على سبيل المثال، عند حذف شيء من قاعدة البيانات، تريد أن تعرف عدد الصفوف التي حُذفت. | ||
== آلية الحل == | == آلية الحل == | ||
# أنشئ تابع استعلام جديد ليُعيد ما يقوم به التابع الأصلي. | # أنشئ تابع استعلام جديد ليُعيد ما يقوم به التابع الأصلي. | ||
# غيِّر التابع الأصلي بحيث يعيد فقط نتيجة استدعاء تابع الاستعلام الجديد. | # غيِّر التابع الأصلي بحيث يعيد فقط نتيجة استدعاء تابع الاستعلام الجديد. | ||
# استبدل كافة المراجع إلى التابع الأصلي باستدعاءات تابع الاستعلام. وضع | # استبدل كافة المراجع إلى التابع الأصلي باستدعاءات تابع الاستعلام. وضع استدعاءً إلى تابع المُعدِّل مباشرةً قبل هذا السطر. سيجنبك هذا الآثارَ الجانبية في حالة إذا كان التابع الأصلي قد استُخدِم في شرط لمعامل شرطي أو حلقة تكرار. | ||
# تخلص من شيفرة إعادة القيمة في التابع الأصلي، الذي أصبح الآن | # تخلص من شيفرة إعادة القيمة في التابع الأصلي، الذي أصبح الآن تابعًا مُعدِّلًا بشكل مناسب. | ||
== انظر أيضًا == | == انظر أيضًا == | ||
سطر 40: | سطر 40: | ||
[[تصنيف:Refactoring]] | [[تصنيف:Refactoring]] | ||
[[تصنيف:Refactoring Techniques]] | [[تصنيف:Refactoring Techniques]] | ||
[[تصنيف:Simplifying Method Calls]] | [[تصنيف:Refactoring Simplifying Method Calls]] |
المراجعة الحالية بتاريخ 14:17، 25 فبراير 2019
المشكلة
هل لديك تابعٌ يُعيد قيمةً ما ولكن يغيِّر أيضا شيئًا ما داخل الكائن؟
الحل
تقسيم التابع إلى تابعَين منفصلَين. كما يمكن أن نتوقع، يجب على أحدهما أن يعيد القيمة ويُغيِّر الآخر الكائن.
مثال
قبل إعادة التصميم
ينفذ التابع ()getTotlaOutstandingAndSetReadyForSummaries
في الصنف Customer
مهمتين، إذ يعيد قيمة ويضبط قيمة أخرى في الكائن:
بعد إعادة التصميم
فصل التابع التابع ()getTotlaOutstandingAndSetReadyForSummaries
إلى تابعين هما: الأول ()getTotlaOutstanding
لجلب قيمة، والآخر ()setReadyForSummaries
لضبط حالةٍ في الكائن:
لم إعادة التصميم؟
تفصل تقنية إعادة التصميم هذه مسؤولية الأوامر عن الاستعلامات (Command and Query Responsibility Segregation). ويدعو هذا المبدأ إلى فصل شيفرة الحصول على البيانات عن الشيفرة التي تغير شيئًا داخل الكائن.
وتسمَّى شيفرة التي تجلب بيانات "استعلام" (query). وتسمَّى شيفرة التي تغير الأشياء في الحالة المرئية (visible state) للكائن "مُعدِّل" (modifier). عند الجمع بين الاستعلام والمُعدِّل، لن يكون لديك سبيل للحصول على البيانات دون إجراء تغييرات على حالتها. وبعبارة أخرى، يمكنك أن تطرح السؤال وتغير الإجابة حتى أثناء تلقيها. وتزداد هذه المشكلة حدةً عندما لا يعرف الشخص الذي يستدعي الاستعلام عن "الآثار الجانبية" للتابع، التي كثيرًا ما تؤدي إلى أخطاء وقت التشغيل.
ولكن تذكَّر أنَّ الآثار الجانبية لا تكون خطيرة إلا في حالة المُعدِّلات التي تغير الحالة المرئية للكائن. على سبيل المثال، يمكن الوصول إلى هذه الحقول من الواجهة العامة لكائن، أو عنصر في قاعدة بيانات، أو في الملفات وما إلى ذلك. إذا كان المُعدِّل يُخزِّن فقط عملية معقدة ويحفظها داخل الحقل الخاص لصنف ما، فإنه بالكاد قد يسبب آثارًا جانبية.
فوائد تطبيق الحل
- إذا كان لديك استعلام لا يغير حالة البرنامج، يمكنك استدعائه مرات عديدة كما تريد دون الحاجة إلى القلق حول التغييرات غير المقصودة في النتيجة الناتجة عن مجرد حقيقة استدعاء التابع.
مساوئ تطبيق الحل
- في بعض الحالات يكون من الملائم الحصول على البيانات بعد تنفيذ أمر. على سبيل المثال، عند حذف شيء من قاعدة البيانات، تريد أن تعرف عدد الصفوف التي حُذفت.
آلية الحل
- أنشئ تابع استعلام جديد ليُعيد ما يقوم به التابع الأصلي.
- غيِّر التابع الأصلي بحيث يعيد فقط نتيجة استدعاء تابع الاستعلام الجديد.
- استبدل كافة المراجع إلى التابع الأصلي باستدعاءات تابع الاستعلام. وضع استدعاءً إلى تابع المُعدِّل مباشرةً قبل هذا السطر. سيجنبك هذا الآثارَ الجانبية في حالة إذا كان التابع الأصلي قد استُخدِم في شرط لمعامل شرطي أو حلقة تكرار.
- تخلص من شيفرة إعادة القيمة في التابع الأصلي، الذي أصبح الآن تابعًا مُعدِّلًا بشكل مناسب.