كيف تنفذ بكفاءة نمط المراقب إذا كان الموضوع حاوية ضخمة؟

StackOverflow https://stackoverflow.com/questions/955155

سؤال

نحن جميعا نعرف نمط المراقب: لديك موضوع قادر على إخطار وتحديث قائمة مراقبين بتغيرات الدولة. لنفترض الآن أن الموضوع الذي ترغب في ملاحظته هو حاوية، وترغب في ملاحظة الحاوية نفسها، أي إضافة عنصر وحذف العناصر، وكذلك العناصر الموجودة، أي تحديثات الدولة لعناصر الحاويات.

كيف يمكنك تنفيذ آلية التحديث بحيث تكون سريعة فيما يتعلق بإدراج العنصر والحذف عند تخزين كميات هائلة من الكائنات في الحاوية الخاصة بك؟ خاصه،

  • هل تستخدم نفس النوع من الحاويات في النسخة المحلية من المراقبين؟
  • هل هناك اختيار ذكي للحاوية التي يجب على المراقبين استخدامها؟ (على سبيل المثال، هل سيكون أسرع، كما أقول، دائما استخدام الأشجار المتوازنة، حتى لو كنت تراقب قائمة مرتبطة؟)
  • كيف ترجم سرعان ما تترجم جهاز استئناف في الحاوية المرصودة إلى جهاز كمتقل في حاوية المراقب؟ (تافهة للمصفوفات، من الصعب القوائم المرتبطة؟)

إذا كانت الحاوية الخاصة بك قائمة مرتبطة على سبيل المثال، فيمكنك إدراج عناصر في وقت ثابت. إذا كان يجب على المراقبين M للتكرار من خلال القائمة التي تحتوي على عناصر n، ثم التحديث يأخذ O (N * M) الوقت المتوقع.

إذا كانت الحاوية الخاصة بك هي صفيف، فإن تغيير عنصر يأخذ وقتا ثابتا، وتحديث المراقبين M يأخذ O (M) إذا قمت بتمرير فهرس العناصر، O (N * M) إذا كان على المراقبين التكرار من خلال الصفيف.

إذا كان ذلك يساعد، فكر في الأمثلة التالية:

مثال 1. أنت تكتب نظام تشغيل. الموضوع الذي ترغب في ملاحظته هو نظام الملفات وملفاته. وجهات نظرك هي مستكشف ملفات، فهرس، وتطبيقات أخرى. كنت ترغب في تحديث المراقبين عند إضافة الملفات أو حذفها أو تعديلها.

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

كيف يمكنك التعامل مع الحالة التي يتم حذفها دليل دليل كامل أو أن "53rd St" يتم إعادة تسمية "dijkstra st"؟

هل كانت مفيدة؟

المحلول

بطريقة ما، يجب عليك تحويل الحاوية إلى موضوع.

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

عدل] نظرا لأنك تطلب طريقة فعالة، فإن الإجابة العامة هي "ذلك يعتمد". لا تحتوي أنماط التصميم على حل "مناسب الحجم". إنها قواعد عامة كيفية الاقتراب من مشكلة. كيف تحتاج إلى تنفيذ القواعد في وضع معين هو شيء تحل فيه عندما تكون في الموقف.

بشكل عام، إذا كان مراقبيك بحاجة إلى تحديد التغييرات الصغيرة (أي تغيير سمة أو إضافة عنصر)، يجب أن تحتوي رسالة الإعلام على معلومات كافية يمكنها القيام بذلك بكفاءة. لذلك إذا كان لديك قائمة كبيرة وإدراج، فقم بإرسال القائمة وفهرس العنصر الجديد بالإضافة إلى "العنصر كما هو إدراج".

أما بالنسبة لتغييرات السمة، فهناك حلولان. واحد هو إضافة مراقب إلى كل عنصر في القائمة. قد يكون هذا بطيئا وتحتاج إلى الكثير من الكبش ولكنه يعني أنه يمكنك إضافة عدة أنواع إلى نفس القائمة.

بدلا من ذلك، يمكنك الحصول على "تعديل عنصر في قائمة القائمة". هذا يعني أنه يحظر تغيير العناصر مباشرة، يجب عليك دائما استخدام الخدمة. يمكن أن تعمل الخدمة بعد ذلك كموضوع وإرسال الإخطارات مع العنصر، والقيمة القديمة والمتغيرة وربما مع الفهرس في القائمة.

EDIT2] القاعدة العامة هي جمع أكبر قدر ممكن من المعلومات حول التغيير قدر الإمكان وتمرير ذلك إلى المراقبين. لكنه يعتمد حقا على مشكلتك المحددة. دعنا نقول المراقب يجلس على جهاز بعيد. في هذه الحالة، لا توجد طريقة فعالة لإرسالها القائمة بأكملها. يمكنك فقط إرسالها "تم إدراج البند x" وآمل أن يكفي. إذا كانت الحاوية ليس لها طريقة لاحظت التغييرات (على سبيل المثال، صفحات ويب جديدة على موقع ويب)، فإن الحاوية يجب أن تعبر الموقع بأكمله مرارا وتكرارا للعثور على تغييرات يمكنها اختيار المراقبين بطريقة فعالة.

مرة أخرى، تعتمد التفاصيل حقا على الوضع المحدد. يدير Google ألف من العناكب على الويب التي تزور ملايين صفحات الويب كل ساعة. لفترة طويلة، كان هذا "فعالا" (كما هو الحال في "الطريقة الوحيدة"). منذ فترة من الوقت، تم تنفيذ بروتوكول "خريطة الموقع" الذي يسمح بالإيدحين بتحويل مواقع الويب الخاصة بهم إلى مواضيع يمكنهم معرفة أوبزرفر Google عن التغييرات.

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

EDID3] إليك بعض الأمثلة لاستخدامات نمط المراقب:

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

  • تستخدم Google بروتوكول خريطة الموقع لتحويل مواقع الويب إلى مواضيع نظرا لأن هذا أكثر كفاءة بكثير من اجتياز الموقع بأكمله مرارا وتكرارا، حتى إذا طلبت فقط وقت التعديل الأخير لعنوان URL (HTTP HTTL).

  • توفر أنظمة الملفات في Windows و Linux إعلامات لإخبار التطبيقات حول الملفات الجديدة أو المحذوفة. المشكلة الرئيسية هنا هي ما يجب أن يحدث عند تغيير الملفات أثناء تشغيل التطبيق. قل لديك تطبيق يحافظ على المجموع الاختباري للملفات في دليل. من الواضح، كنت ترغب في معرفة التغييرات عندما انخفض التطبيق ولكن هذا يعني أن خدمة الإعلام سيتعين على تغيير التغيير الأخير الذي أرسلته. حتى هنا، يتعين على التطبيق قراءة الشجرة بأكملها عند بدء التشغيل لمعرفة أي شيء قد يكون قد فاتته، ويحتاج إلى استخدام نمط المراقب للتغييرات التي تحدث أثناء تشغيلها.

  • عميل البريد هو مراقب. ستقوم بإخبار خادم البريد مع معرف البريد الإلكتروني الأخير الذي شاهدا وسيخبره الخادم عن أي منها جديد.

  • عندما يكون لديك الكثير من التغييرات السمة في نموذج معقد، عادة ما تكون الطريقة الوحيدة لمركز جميع التغييرات (اجعلها تعمل من خلال مكان واحد) وإرفاق المراقبين هناك (بدلا من إرفاق المراقبين N إلى كائنات فردية). في هذا التنفيذ، يمكن للمراقبين أن يقولوا "أنا مهتم بأي تغيير في أي مكان" أو "تغيير الحقل X في أي موضوع" أو "أي تغيير في الموضوع Y" (آخر واحد يتضاعف عادة باعتباره "تغيير الحقل" س في الموضوع Y "- سيقوم المراقب ببساطة بتجاهل التغييرات في الحقول! = x).

نصائح أخرى

لماذا لا نمط المراقب نفسه؟

يحتاج الموضوع لإبلاغ المراقب عن الأحداث المثيرة للاهتمام. ثم يجب على المراقب إرسالها إلى الأطراف المهتمة (المشتركين).

طبيعة الموضوع ليست بأي أهمية هنا. (ما لم أفهم سؤالك خطأ).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top