الفرق بين المراجعتين ل"Refactoring/duplicate observed data"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
ط (تدقيق)
ط (مراجعة)
 
(مراجعة متوسطة واحدة بواسطة مستخدم واحد آخر غير معروضة)
سطر 2: سطر 2:
 
== المشكلة ==
 
== المشكلة ==
 
هل بيانات النطاق المخزَّنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟ إذًا، إليك الحل.
 
هل بيانات النطاق المخزَّنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟ إذًا، إليك الحل.
 
 
== الحل ==
 
== الحل ==
 
فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية (GUI).
 
فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية (GUI).
 +
 +
=== مثال ===
 +
 +
==== قبل إعادة التصميم ====
 +
إليك المخطط التالي لبيانات نطاق مخزَّنة في أصناف والمسؤولة عن الواجهة الرسومية:[[ملف:Duplicate Observed Data - Before.png|بديل=بيانات النطاق مخزَّنة في أصناف.|بدون|تصغير|بيانات النطاق مخزَّنة في أصناف.]]
 +
 +
==== بعد إعادة التصميم ====
 +
يصبح المخطط السابق بالشكل التالي بعد إعادة التصميم:[[ملف:Duplicate Observed Data - After.png|بديل=فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.|بدون|تصغير|فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.]]
  
 
== لم إعادة التصميم؟ ==
 
== لم إعادة التصميم؟ ==
سطر 15: سطر 22:
  
 
== متى يُترَك هذا الحل؟ ==
 
== متى يُترَك هذا الحل؟ ==
* لا تنطبق تقنية إعادة التصميم هذه، والتي تُنفَّذ في نموذجها الكلاسيكي باستخدام قالب [[Refactoring/observer|المُراقِب]] (Observer)، على تطبيقات الويب، إذ يُعاد إنشاء كافة الأصناف بين الاستعلامات المُرسَلة إلى خادم الويب.
+
* لا تنطبق تقنية إعادة التصميم هذه، والتي تُنفَّذ في نموذجها الكلاسيكي باستخدام قالب [[Design Pattern/observer|المُراقِب]] (Observer)، على تطبيقات الويب، إذ يُعاد إنشاء كافة الأصناف بين الاستعلامات المُرسَلة إلى خادم الويب.
 
* بنفس الطريقة، يمكن كذلك تبرير المبدأ العام لاستخراج منطق العمل إلى أصناف منفصلة لتطبيقات الويب. ولكن سيُنفذ هذا باستخدام تقنيات مختلفة لإعادة التصميم اعتمادًا على كيفية تصميم النظام الخاص بك.
 
* بنفس الطريقة، يمكن كذلك تبرير المبدأ العام لاستخراج منطق العمل إلى أصناف منفصلة لتطبيقات الويب. ولكن سيُنفذ هذا باستخدام تقنيات مختلفة لإعادة التصميم اعتمادًا على كيفية تصميم النظام الخاص بك.
  
 
== آلية الحل ==
 
== آلية الحل ==
# إخفاء إمكانية الوصول المباشر إلى بيانات النطاق في الصنف GUI. لهذا، فمن الأفضل استخدام [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]]. فيمكنك إنشاء المتلقي (getter) والضابط (setter) لهذه البيانات.
+
# إخفاء إمكانية الوصول المباشر إلى بيانات النطاق في الصنف GUI. لهذا، فمن الأفضل استخدام [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]]. فيمكنك إنشاء الجالب (getter) والضابط (setter) لهذه البيانات.
 
# تُستخدم الضوابط لتعيين قيم الحقل الجديدة في معالجات أحداث الصنف GUI. وسيتيح لك هذا تمرير هذه القيم إلى كائن النطاق المقترن.
 
# تُستخدم الضوابط لتعيين قيم الحقل الجديدة في معالجات أحداث الصنف GUI. وسيتيح لك هذا تمرير هذه القيم إلى كائن النطاق المقترن.
 
# إنشاء صنف مجال (domain class) ونسخ الحقول الضرورية من الصنف GUI إليه. إنشاء المتلقي والضابط لجميع هذه الحقول.
 
# إنشاء صنف مجال (domain class) ونسخ الحقول الضرورية من الصنف GUI إليه. إنشاء المتلقي والضابط لجميع هذه الحقول.
# إنشاء نمط [[Refactoring/observer|مراقب]] لهذين الصنفين:  
+
# إنشاء نمط [[Design Pattern/observer|مراقب]] لهذين الصنفين:  
 
#* أنشئ مصفوفة في صنف النطاق لتخزين كائنات المراقبة (كائنات GUI)، بالإضافة إلى توابع التسجيل والحذف والإشعار.
 
#* أنشئ مصفوفة في صنف النطاق لتخزين كائنات المراقبة (كائنات GUI)، بالإضافة إلى توابع التسجيل والحذف والإشعار.
 
#*  أنشئ في الصنف GUI حقلًا لتخزين المراجع في صنف النطاق بالإضافة إلى التابع <code>update()</code>‎، الذي سيتفاعل مع التغييرات في الكائن ويُحدِّث قيم الحقول في الصنف GUI. علمًا بأنه يجب تأسيس تحديثات القيمة مباشرةً في التابع لتجنب العودية.
 
#*  أنشئ في الصنف GUI حقلًا لتخزين المراجع في صنف النطاق بالإضافة إلى التابع <code>update()</code>‎، الذي سيتفاعل مع التغييرات في الكائن ويُحدِّث قيم الحقول في الصنف GUI. علمًا بأنه يجب تأسيس تحديثات القيمة مباشرةً في التابع لتجنب العودية.
سطر 30: سطر 37:
  
 
== انظر أيضًا ==
 
== انظر أيضًا ==
* [[Refactoring/observer|قالب المُراقِب.]]
+
* [[Design Pattern/observer|قالب المُراقِب.]]
 
* [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]].
 
* [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]].
 
* [[Refactoring/large class|الأصناف الواسعة]].
 
* [[Refactoring/large class|الأصناف الواسعة]].

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

المشكلة

هل بيانات النطاق المخزَّنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟ إذًا، إليك الحل.

الحل

فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية (GUI).

مثال

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

إليك المخطط التالي لبيانات نطاق مخزَّنة في أصناف والمسؤولة عن الواجهة الرسومية:

بيانات النطاق مخزَّنة في أصناف.
بيانات النطاق مخزَّنة في أصناف.

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

يصبح المخطط السابق بالشكل التالي بعد إعادة التصميم:

فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.
فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.

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

إذا كنت تريد أن يكون لديك واجهات عرض متعددة لنفس البيانات (على سبيل المثال، تطبيق لسطح المكتب وتطبيق للهاتف المحمول). إذا لم تنجح في فصل وواجهة المستخدم الرسومية عن النطاق، فستمر بوقت عصيب جدًا لتجنب تكرار التعليمات البرمجية والوقوع في عدد كبير من الأخطاء.

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

  • يمكن تقسيم المسؤولية بين أصناف منطق العمل وأصناف العرض (راجع مبدأ المسؤولية الفردية)، مما يجعل البرنامج أكثر قابلية للقراءة والفهم.
  • إذا كنت بحاجة إلى إضافة واجهة عرض جديدة، لن يكون إنشاء أصناف عرض جديدة بحاجة إلى أي تعديل لشيفرة منطق العمل (راجع مبدأ مفتوح/مغلق).
  • يمكن الآن لأشخاص مختلفين العمل على منطق العمل وواجهات المستخدم.

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

  • لا تنطبق تقنية إعادة التصميم هذه، والتي تُنفَّذ في نموذجها الكلاسيكي باستخدام قالب المُراقِب (Observer)، على تطبيقات الويب، إذ يُعاد إنشاء كافة الأصناف بين الاستعلامات المُرسَلة إلى خادم الويب.
  • بنفس الطريقة، يمكن كذلك تبرير المبدأ العام لاستخراج منطق العمل إلى أصناف منفصلة لتطبيقات الويب. ولكن سيُنفذ هذا باستخدام تقنيات مختلفة لإعادة التصميم اعتمادًا على كيفية تصميم النظام الخاص بك.

آلية الحل

  1. إخفاء إمكانية الوصول المباشر إلى بيانات النطاق في الصنف GUI. لهذا، فمن الأفضل استخدام التغليف الداخلي للحقول. فيمكنك إنشاء الجالب (getter) والضابط (setter) لهذه البيانات.
  2. تُستخدم الضوابط لتعيين قيم الحقل الجديدة في معالجات أحداث الصنف GUI. وسيتيح لك هذا تمرير هذه القيم إلى كائن النطاق المقترن.
  3. إنشاء صنف مجال (domain class) ونسخ الحقول الضرورية من الصنف GUI إليه. إنشاء المتلقي والضابط لجميع هذه الحقول.
  4. إنشاء نمط مراقب لهذين الصنفين:  
    • أنشئ مصفوفة في صنف النطاق لتخزين كائنات المراقبة (كائنات GUI)، بالإضافة إلى توابع التسجيل والحذف والإشعار.
    •  أنشئ في الصنف GUI حقلًا لتخزين المراجع في صنف النطاق بالإضافة إلى التابع update()‎، الذي سيتفاعل مع التغييرات في الكائن ويُحدِّث قيم الحقول في الصنف GUI. علمًا بأنه يجب تأسيس تحديثات القيمة مباشرةً في التابع لتجنب العودية.
    • أنشئ مثيل النطاق في باني الصنف GUI واحفظه في حقل سبق إنشائه. وسجل الكائن GUI كمراقب في كائن النطاق.
    • في ضوابط حقول صنف النطاق، استدعِ التابع لإشعار المراقب (بعبارة أخرى، تابعًا للتحديث في الصنف GUI)، من أجل تمرير القيم الجديدة إلى GUI.
    • غيِّر ضوابط حقول الصنف GUI بحيث تُعيَّن قيم جديدة في كائن النطاق مباشرة. وانتبه إلى التأكد من أن القيم ليست موضوعة من خلال ضابط صنف نطاق وإلا سينتج عودية لانهائية.

انظر أيضًا

مصادر