الفرق بين المراجعتين لصفحة: «Refactoring/duplicate observed data»

من موسوعة حسوب
ط مراجعة
 
(مراجعتان متوسطتان بواسطة مستخدمين اثنين آخرين غير معروضتين)
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: تكرار البيانات المرُاقَبة (Duplicate Observed Data)}}</noinclude>
<noinclude>{{DISPLAYTITLE: تكرار البيانات المرُاقَبة (Duplicate Observed Data)}}</noinclude>
== المشكلة ==
== المشكلة ==
هل بيانات النطاق المخزنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟
هل بيانات النطاق المخزَّنة في أصناف هي المسؤولة عن واجهة المستخدم الرسومية (GUI)؟ إذًا، إليك الحل.
== الحل ==
فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية (GUI).
 
=== مثال ===
 
==== قبل إعادة التصميم ====
إليك المخطط التالي لبيانات نطاق مخزَّنة في أصناف والمسؤولة عن الواجهة الرسومية:[[ملف:Duplicate Observed Data - Before.png|بديل=بيانات النطاق مخزَّنة في أصناف.|بدون|تصغير|بيانات النطاق مخزَّنة في أصناف.]]


== الحل ==
==== بعد إعادة التصميم ====
فصل البيانات في أصناف منفصلة، لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية GUI.
يصبح المخطط السابق بالشكل التالي بعد إعادة التصميم:[[ملف:Duplicate Observed Data - After.png|بديل=فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.|بدون|تصغير|فصل البيانات في أصناف منفصلة لضمان الاتصال والتزامن بين صنف النطاق وواجهة المستخدم الرسومية.]]


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


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


== متى يُترك هذا الحل؟ ==
== متى يُترَك هذا الحل؟ ==
* لا تنطبق تقنية إعادة التصميم هذه، والتي تُنفَّذ في نموذجها الكلاسيكي باستخدام قالب المُراقِب [[Refactoring/observer|Observer]]، علي تطبيقات الويب، حيث يُعاد إنشاء كافة الأصناف بين الاستعلامات المُرسَلة إلى خادم الويب.
* لا تنطبق تقنية إعادة التصميم هذه، والتي تُنفَّذ في نموذجها الكلاسيكي باستخدام قالب [[Design Pattern/observer|المُراقِب]] (Observer)، على تطبيقات الويب، إذ يُعاد إنشاء كافة الأصناف بين الاستعلامات المُرسَلة إلى خادم الويب.
* بنفس الطريقة، يمكن كذلك تبرير المبدأ العام لاستخراج منطق العمل إلى أصناف منفصلة لتطبيقات الويب. ولكن سيُنفذ هذا باستخدام تقنيات مختلفة لإعادة التصميم اعتمادًا على كيفية تصميم النظام الخاص بك.
* بنفس الطريقة، يمكن كذلك تبرير المبدأ العام لاستخراج منطق العمل إلى أصناف منفصلة لتطبيقات الويب. ولكن سيُنفذ هذا باستخدام تقنيات مختلفة لإعادة التصميم اعتمادًا على كيفية تصميم النظام الخاص بك.


== آلية الحل ==
== آلية الحل ==
# إخفاء إمكانية الوصول المباشر إلى بيانات النطاق في صنف GUI. لهذا فمن الأفضل استخدام التغليف الداخلي للحقول ([[Refactoring/self encapsulate field|Self Encapsulate Field]]). فيمكنك إنشاء المتلقي والضابط لهذه البيانات.
# إخفاء إمكانية الوصول المباشر إلى بيانات النطاق في الصنف GUI. لهذا، فمن الأفضل استخدام [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]]. فيمكنك إنشاء الجالب (getter) والضابط (setter) لهذه البيانات.
# تُستخدم الضوابط لتعيين قيم الحقل الجديدة في معالجات أحداث صنف GUI. وسيتيح لك هذا تمرير هذه القيم إلى كائن النطاق المقترن.
# تُستخدم الضوابط لتعيين قيم الحقل الجديدة في معالجات أحداث الصنف GUI. وسيتيح لك هذا تمرير هذه القيم إلى كائن النطاق المقترن.
# إنشاء صنف مجال ونسخ الحقول الضرورية من صنف GUI إليه. إنشاء المتلقي والضابط لجميع هذه الحقول.
# إنشاء صنف مجال (domain class) ونسخ الحقول الضرورية من الصنف GUI إليه. إنشاء المتلقي والضابط لجميع هذه الحقول.
# إنشاء نمط مراقب Observer لهذين الصنفين:  
# إنشاء نمط [[Design Pattern/observer|مراقب]] لهذين الصنفين:  
#* أنشئ مصفوفة في صنف النطاق لتخزين كائنات المراقبة (كائنات GUI)، بالإضافة إلى توابع التسجيل والحذف والإشعار.
#* أنشئ مصفوفة في صنف النطاق لتخزين كائنات المراقبة (كائنات GUI)، بالإضافة إلى توابع التسجيل والحذف والإشعار.
#*  أنشئ في صنف GUI حقل لتخزين المراجع في صنف النطاق بالإضافة إلى تابع update()‎، الذي سيتفاعل مع التغييرات في الكائن ويُحدِّث قيم الحقول في صنف GUI. علمًا بأنه يجب تأسيس تحديثات القيمة مباشرةً في التابع لتجنب العودية.
#*  أنشئ في الصنف GUI حقلًا لتخزين المراجع في صنف النطاق بالإضافة إلى التابع <code>update()</code>‎، الذي سيتفاعل مع التغييرات في الكائن ويُحدِّث قيم الحقول في الصنف GUI. علمًا بأنه يجب تأسيس تحديثات القيمة مباشرةً في التابع لتجنب العودية.
#* أنشئ مثيل النطاق في مُنشئ الصنف GUI واحفظه في حقل سبق إنشائه. وسجل كائن GUI كمراقب في كائن النطاق.
#* أنشئ مثيل النطاق في باني الصنف GUI واحفظه في حقل سبق إنشائه. وسجل الكائن GUI كمراقب في كائن النطاق.
#* في ضوابط حقول صنف النطاق، استدع التابع لإشعار المراقب (وبعبارة أخرى، تابع للتحديث في الصنف GUI)، من أجل تمرير القيم الجديدة إلى GUI.
#* في ضوابط حقول صنف النطاق، استدعِ التابع لإشعار المراقب (بعبارة أخرى، تابعًا للتحديث في الصنف GUI)، من أجل تمرير القيم الجديدة إلى GUI.
#* غيِّر ضوابط حقول الصنف GUI بحيث تُعيَّن قيم جديدة في كائن النطاق مباشرة. وانتبه إلى التأكد من أن القيم ليست موضوعة من خلال ضابط صنف نطاق وإلا سينتج عودية لانهائية.
#* غيِّر ضوابط حقول الصنف GUI بحيث تُعيَّن قيم جديدة في كائن النطاق مباشرة. وانتبه إلى التأكد من أن القيم ليست موضوعة من خلال ضابط صنف نطاق وإلا سينتج عودية لانهائية.


== انظر أيضًا ==
== انظر أيضًا ==
* قالب المُراقِب [[Refactoring/observer|Observer]].
* [[Design Pattern/observer|قالب المُراقِب.]]
* التغليف الداخلي للحقول ([[Refactoring/self encapsulate field|Self Encapsulate Field]]).
* [[Refactoring/self encapsulate field|التغليف الداخلي للحقول]].
* الأصناف الواسعة ([[Refactoring/large class|Large Classes]]).
* [[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 بحيث تُعيَّن قيم جديدة في كائن النطاق مباشرة. وانتبه إلى التأكد من أن القيم ليست موضوعة من خلال ضابط صنف نطاق وإلا سينتج عودية لانهائية.

انظر أيضًا

مصادر