هل ما زلت تتذكر كيف تعاون رجال العصابات في فيلم الشرطة والعصابات؟ عندما تكون العصابة سطو ، يأخذ شخص أو شخصان دائمًا الريح عند الباب. إذا كانت هناك أي حركة ، فسيتم إخطار الشركاء في الداخل على الفور بالتراجع بشكل عاجل. ربما لا يعرف الشخص الذي يدع الأخبار بالضرورة كل شريك فيه ؛ وقد يكون هناك أخ أصغر جديد لا يعرف الشخص الذي يسمح للأخبار. ولكن هذا لا شيء ، لا يمكن أن يؤثر على اتصالاتهم لأن لديهم رمز تم الاتفاق عليه.
هاها ، العلاقة بين Air Venter و Thief المذكورة أعلاه هي مثال حي لنمط المراقب في الواقع.
يُعرف وضع المراقب أيضًا باسم وضع النشر/الاشتراك. يحدد GOF نمط المراقب على النحو التالي: يحدد الاعتماد واحد إلى أقصى بين الكائنات. عندما تتغير حالة الكائن ، يتم إخطار جميع الكائنات التي تعتمد عليه وتحديثها تلقائيًا.
هنا سأتحدث أولاً عن مبدأ مهم للتصميم الموجهة للكائنات - مبدأ المسؤولية الفردية. لذلك ، يجب أن يركز كل كائن من النظام على التجريدات المنفصلة في مجال المشكلة. لذلك ، من الناحية المثالية ، فإن الكائن يفعل شيئًا واحدًا فقط. هذا يجلب العديد من الفوائد في التنمية: إنه يوفر قابلية إعادة الاستخدام والصيانة ، وهو أيضًا أساس جيد لإعادة التهيئة.
لذلك ، تستند جميع أنماط التصميم تقريبًا إلى مبدأ التصميم الأساسي هذا. أعتقد أن أصل نموذج المراقب يجب أن يكون في معالجة بيانات واجهة المستخدم الرسومية وبيانات الأعمال ، لأن معظم الأمثلة التي تشرح نموذج المراقب الآن هذا الموضوع. ومع ذلك ، فإن تطبيق وضع المراقب لا يقتصر بأي حال من الأحوال على هذا الجانب.
حسنًا ، يتطلب فهم التعريف دائمًا مثيلات لتحليلها. حسابات خدمة WeChat تحظى بشعبية كبيرة في الوقت الحاضر. دعنا نقدم لك نموذج المراقب مع خلفية حسابات خدمة WeChat.
انظر إلى الصورة:
كل مستخدم لديه 3 أسطر في الصورة أعلاه ، والتي تم حذفها من أجل توضيح الصورة.
كما هو موضح في الصورة أعلاه ، فإن رقم الخدمة هو موضوعنا والمستخدم هو المراقب. الآن نوضح الوظائف التالية:
1. حساب الخدمة هو الموضوع ، والأعمال تدفع الرسائل
2. يحتاج المراقبون فقط إلى الاشتراك في الموضوع ، وسيتم إرسالهم بمجرد وجود أخبار جديدة.
3. قم بإلغاء الاشتراك عندما لا تريد رسالة الموضوع هذه
4. طالما أن حساب الخدمة لا يزال موجودًا ، فسيتم الاشتراك في شخص ما. الآن دعونا نلقي نظرة على مخطط الفصل لنمط المراقب:
التالي هو وقت الكود ، نقوم بمحاكاة حساب خدمة اليانصيب WeChat 3D وبعض المشتركين.
أولاً ، ابدأ في الكتابة عن واجهة موضوعنا وواجهة المراقب:
حزمة com.zhy.pattern.observer ؛ / ** * واجهة الموضوع ، يجب أن تنفذ جميع الموضوعات هذه الواجهة * * Author Zhy * */ واجهة عامة موضوع {/ ** * سجل مراقب * * param observer */ public void registerObserver (Observer Observer) ؛ / ** * قم بإزالة مراقب * * param observer */ public void removeObserver (Observer Observer) ؛ / *** إخطار جميع المراقبين*/ public void notifyObservers () ؛ } package com.zhy.pattern.observer ؛ / *** Author Zhy جميع المراقبين يحتاجون إلى تنفيذ هذه الواجهة*/ الواجهة العامة Observer {public void update (String msg) ؛ }فئة تنفيذ رقم الخدمة ثلاثية الأبعاد التالية:
حزمة com.zhy.pattern.observer ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ الفئة العامة Objectfor3d تنفذ الموضوع {قائمة خاصة <Soncerver> المراقبين = ArrayList جديد <soberver> () ؛ / *** رقم يانصيب ثلاثي الأبعاد*/ سلسلة خاصة msg ؛ Override public void registerObserver (Observer Observer) {observers.add (Observer) ؛ } Override public void removeObserver (Observer Observer) {int index = observers.indexof (observer) ؛ if (index> = 0) {jostervers.remove (index) ؛ }} Override public void notifyObservers () {for (observer observer: observers) {observer.update (msg) ؛ }} / ** * رسالة تحديث الموضوع * * param msg * / public void setMsg (String msg) {this.msg = msg ؛ eletiplesoBservers () ؛ }}محاكاة مستخدمين:
حزمة com.zhy.pattern.observer ؛ الطبقة العامة Observer1 تنفذ Observer {موضوع خاص ؛ Observer1 (موضوع الموضوع) {this.subject = موضوع ؛ الموضوع. RegisterObserver (هذا) ؛ } Override public void update (String msg) {system.out.println ("Observer1 يحصل على الرقم ثلاثي الأبعاد ->" + msg + "، أريد كتابته.") ؛ }} حزمة com.zhy.pattern.observer ؛ الطبقة العامة Observer2 تنفذ Observer {موضوع خاص ؛ ObserVer2 (موضوع الموضوع) {this.subject = object ؛ الموضوع. RegisterObserver (هذا) ؛ } Override Public Void Update (String msg) {system.out.println ("يحصل Observer2 على الرقم ثلاثي الأبعاد ->" + msg + "أريد أن أخبر زملائي في الغرفة.") ؛ }} يمكن ملاحظة أن جميع المستخدمين الذين يشتركون في الرسائل إليها يتم الحفاظ عليها في حساب الخدمة ، ويتم إخطار جميع المستخدمين عندما تكون هناك رسالة جديدة في حساب الخدمة. الهندسة المعمارية بأكملها عبارة عن اقتران فضفاض ، ولا يعتمد تنفيذ السمة على المستخدم. عند إضافة مستخدم جديد ، لا يلزم تغيير رمز السمة ؛ كيف يعالج المستخدم البيانات التي تم الحصول عليها لا علاقة لها بالموضوع ؛
أخيرًا ، انظر إلى رمز الاختبار:
حزمة com.zhy.pattern.observer.test ؛ استيراد com.zhy.pattern.observer.objectfor3d ؛ استيراد com.zhy.pattern.observer.observer ؛ استيراد com.zhy.pattern.observer.observer1 ؛ استيراد com.zhy.pattern.observer.observer2 ؛ استيراد com.zhy.pattern.observer.subject ؛ اختبار الفئة العامة {public static void main (string [] args) {// محاكاة رقم خدمة ثلاثي الأبعاد objectfor3d obserfor3d = new Objectfor3d () ؛ // customer1 observer observer1 = new Observer1 (stersionfor3d) ؛ Observer ObserVer2 = new Observer2 (thispfor3d) ؛ thispfor3d.setmsg ("20140420's 3D الرقم 3D هو: 127") ؛ thispfor3d.setmsg ("20140421 رقم ثلاثي الأبعاد هو: 333") ؛ }}نتيجة الإخراج:
يحصل ObserVer1 على الرقم ثلاثي الأبعاد -> الرقم ثلاثي الأبعاد 20140420 هو: 127 ، أريد أن أكتبه. يحصل Observer2 على الرقم ثلاثي الأبعاد -> الرقم ثلاثي الأبعاد 20140420 هو: 127 أريد أن أخبر زملائي في الغرفة. يحصل Observer1 على الرقم ثلاثي الأبعاد -> الرقم ثلاثي الأبعاد 20140421 هو: 333 ، أريد أن أكتبه. يحصل Observer2 على الرقم ثلاثي الأبعاد -> الرقم ثلاثي الأبعاد 20140421 هو: 333 أريد أن أخبر زملائي في الغرفة.
هناك العديد من الأماكن في JDK أو AndorID التي تنفذ وضع المراقب ، مثل XXXVIEW.ADDXXXXLISTERNER. بالطبع ، xxxview.setonxxxlistener ليس بالضرورة وضع مراقب ، لأن وضع المراقب هو علاقة واحدة إلى حد. بالنسبة إلى setxxxlistener ، فهي علاقة من 1 إلى 1 ، ويجب أن تسمى رد الاتصال.
مبروك على تعلم وضع المراقب. يتيح لنا وضع المراقب أعلاه كتابته من الصفر. بالطبع ، ساعدتنا Java في تنفيذ وضع Observer ، بمساعدة Java.Util.Observable و Java.Util.Observer.
أدناه نستخدم فصول Java المدمجة لتنفيذ نمط المراقب:
بادئ ذي بدء ، هناك موضوع رقم خدمة اليانصيب ثلاثي الأبعاد:
حزمة com.zhy.pattern.observer.java ؛ استيراد java.util.observable ؛ الطبقة العامة character3d يمتد {private string msg ؛ السلسلة العامة getMsg () {return msg ؛ } / ** * موضوع رسالة تحديث الموضوع * * param msg * / public void setMsg (String msg) {this.msg = msg ؛ setChanged () ؛ eletiplesoBservers () ؛ }}ما يلي هو موضوع رقم خدمة كرة ملون مزدوج:
حزمة com.zhy.pattern.observer.java ؛ استيراد java.util.observable ؛ يمتد موضوع الفئة العامة إلى توسيع نطاق {private string msg ؛ السلسلة العامة getMsg () {return msg ؛ } / ** * موضوع رسالة تحديث الموضوع * * param msg * / public void setMsg (String msg) {this.msg = msg ؛ setChanged () ؛ eletiplesoBservers () ؛ }}أخيرًا ، مستخدمونا:
حزمة com.zhy.pattern.observer.java ؛ استيراد java.util.observable ؛ استيراد java.util.observer ؛ الطبقة العامة Observer1 تنفذ Observer {public void RecistersUbject (يمكن ملاحظتها) } Override public void update (يمكن ملاحظته O ، كائن arg) {if (o eastyof obserfor3d) {thispfor3d obserfor3d = (storberfor3d) o ؛ System.out.println ("thispfor3d's msg ->" + obserfor3d.getmsg ()) ؛ } if (o eastyof thispforssq) {tsborforssq thispforssq = (thisporsforssq) o ؛ system.out.println ("thisporssq's msg ->" + thisporsq.getmsg ()) ؛ }}}انظر إلى رمز الاختبار:
حزمة com.zhy.pattern.observer.java ؛ اختبار الفئة العامة {public static void main (string [] args) {thispfor3d obserfor3d = new thispfor3d () ؛ thispforssq thispforssq = new thispforssq () ؛ Observer1 ObserVer1 = New Observer1 () ؛ ObserVer1.registersUbject (discorfor3d) ؛ ObserVer1.registersUbject (tsborforssq) ؛ thispfor3d.setmsg ("Hello 3D'nums: 110") ؛ Thispforssq.setmsg ("ssq'nums: 12،13،31،5،3،3 15") ؛ }}نتائج الاختبار:
msg thispfor3d -> hello 3d'nums: 110 msg tersfforssq -> ssq'nums: 12،13،31،5،4،3 15
يمكن ملاحظة أنه باستخدام فئات Java المدمجة لتنفيذ نمط المراقب ، فإن الكود موجز للغاية. بالمناسبة ، تم تنفيذ AddObserver و removeObserver و NotifyObservers لنا. كل ما يمكننا رؤيته يمكن ملاحظته هو فئة ، وليس واجهة. في الأساس ، يتمتع الكتاب بموقف سلبي تجاه تصميم جافا. يشعر أن نمط المراقب المدمج في Java ينتهك مبدأ البرمجة الموجهة للواجهة. ومع ذلك ، إذا فكرت في الأمر ، فأنت بالفعل تكتب نمط المراقب هنا (تنفيذنا). تعتبر فكرة الواجهة جيدة جدًا ، ولكن إذا واصلت إضافة العديد من الموضوعات الآن ، فإن DDOBServer و REMOFOBServer و NotifyObservers لكل موضوع هو نفسه بشكل أساسي. لا يمكن للواجهات تنفيذ إعادة استخدام التعليمات البرمجية ، ولا توجد طريقة لاستخدام الوضع المدمج لتحقيق إعادة استخدام هذه الطرق الثلاث ، لذلك أعتقد أنه من المعقول تنفيذ هذه الأساليب الثلاثة في الفصل هنا.