فصل الاستعلامات عن المُعدِّلات (Separate Query from Modifier)
المشكلة
هل لديك تابعٌ يُعيد قيمةً ما ولكن يغيِّر أيضا شيئًا ما داخل الكائن؟
الحل
تقسيم التابع إلى تابعَين منفصلَين. كما يمكن أن نتوقع، يجب على أحدهما أن يعيد القيمة ويُغيِّر الآخر الكائن.
مثال
قبل إعادة التصميم
ينفذ التابع ()getTotlaOutstandingAndSetReadyForSummaries
في الصنف Customer
مهمتين، إذ يعيد قيمة ويضبط قيمة أخرى في الكائن:
بعد إعادة التصميم
فصل التابع التابع ()getTotlaOutstandingAndSetReadyForSummaries
إلى تابعين هما: الأول ()getTotlaOutstanding
لجلب قيمة، والآخر ()setReadyForSummaries
لضبط حالةٍ في الكائن:
لم إعادة التصميم؟
تفصل تقنية إعادة التصميم هذه مسؤولية الأوامر عن الاستعلامات (Command and Query Responsibility Segregation). ويدعو هذا المبدأ إلى فصل شيفرة الحصول على البيانات عن الشيفرة التي تغير شيئًا داخل الكائن.
وتسمَّى شيفرة التي تجلب بيانات "استعلام" (query). وتسمَّى شيفرة التي تغير الأشياء في الحالة المرئية (visible state) للكائن "مُعدِّل" (modifier). عند الجمع بين الاستعلام والمُعدِّل، لن يكون لديك سبيل للحصول على البيانات دون إجراء تغييرات على حالتها. وبعبارة أخرى، يمكنك أن تطرح السؤال وتغير الإجابة حتى أثناء تلقيها. وتزداد هذه المشكلة حدةً عندما لا يعرف الشخص الذي يستدعي الاستعلام عن "الآثار الجانبية" للتابع، التي كثيرًا ما تؤدي إلى أخطاء وقت التشغيل.
ولكن تذكَّر أنَّ الآثار الجانبية لا تكون خطيرة إلا في حالة المُعدِّلات التي تغير الحالة المرئية للكائن. على سبيل المثال، يمكن الوصول إلى هذه الحقول من الواجهة العامة لكائن، أو عنصر في قاعدة بيانات، أو في الملفات وما إلى ذلك. إذا كان المُعدِّل يُخزِّن فقط عملية معقدة ويحفظها داخل الحقل الخاص لصنف ما، فإنه بالكاد قد يسبب آثارًا جانبية.
فوائد تطبيق الحل
- إذا كان لديك استعلام لا يغير حالة البرنامج، يمكنك استدعائه مرات عديدة كما تريد دون الحاجة إلى القلق حول التغييرات غير المقصودة في النتيجة الناتجة عن مجرد حقيقة استدعاء التابع.
مساوئ تطبيق الحل
- في بعض الحالات يكون من الملائم الحصول على البيانات بعد تنفيذ أمر. على سبيل المثال، عند حذف شيء من قاعدة البيانات، تريد أن تعرف عدد الصفوف التي حُذفت.
آلية الحل
- أنشئ تابع استعلام جديد ليُعيد ما يقوم به التابع الأصلي.
- غيِّر التابع الأصلي بحيث يعيد فقط نتيجة استدعاء تابع الاستعلام الجديد.
- استبدل كافة المراجع إلى التابع الأصلي باستدعاءات تابع الاستعلام. وضع استدعاءً إلى تابع المُعدِّل مباشرةً قبل هذا السطر. سيجنبك هذا الآثارَ الجانبية في حالة إذا كان التابع الأصلي قد استُخدِم في شرط لمعامل شرطي أو حلقة تكرار.
- تخلص من شيفرة إعادة القيمة في التابع الأصلي، الذي أصبح الآن تابعًا مُعدِّلًا بشكل مناسب.