1. คำจำกัดความของโหมดผู้สังเกตการณ์:
โหมดผู้สังเกตการณ์เรียกอีกอย่างว่าโหมดการสมัครสมาชิก-เผยแพร่ซึ่งวัตถุเป้าหมายจัดการวัตถุผู้สังเกตการณ์ทั้งหมดขึ้นอยู่กับมันและออกการแจ้งเตือนอย่างแข็งขันเมื่อสถานะเปลี่ยนแปลง โดยปกติจะทำได้โดยการเรียกใช้วิธีการของผู้สังเกตการณ์แต่ละคน รูปแบบนี้มักจะใช้ในระบบประมวลผลเหตุการณ์
1. โครงสร้างทั่วไปของรูปแบบผู้สังเกตการณ์
ก่อนอื่นมาดูคำอธิบายแผนภาพคลาสของรูปแบบผู้สังเกตการณ์:
บทบาทของโหมดผู้สังเกตการณ์มีดังนี้:
หัวเรื่อง (อินเทอร์เฟซหัวข้อบทคัดย่อ): กำหนดชุดของการดำเนินการในรายการผู้สังเกตการณ์ในคลาสธีมรวมถึงการเพิ่มการลบการแจ้งเตือน ฯลฯ
เรื่องที่เป็นรูปธรรม (คลาสหัวข้อเฉพาะ):
ผู้สังเกตการณ์ (อินเทอร์เฟซ Abstract Observer): กำหนดผู้สังเกตการณ์เพื่อยอมรับการดำเนินการในสถานะการอัปเดตคลาสหัวข้อ
Concreteobserver (คลาส Observer เฉพาะ): ใช้ตรรกะเช่นการอัปเดตคลาสหัวข้อการแจ้งเตือนโดยอินเทอร์เฟซ Observer
จากแผนภาพคลาสนี้เราจะเห็นได้ว่าคลาสธีมจะดูแลรายการคลาสที่ใช้อินเทอร์เฟซ Observer คลาสธีมใช้รายการนี้เพื่อดำเนินการชุดของการเพิ่มการลบและการแก้ไขในผู้สังเกตการณ์ คลาส Observer ยังสามารถเรียกใช้วิธีการอัปเดตเพื่อทำความเข้าใจข้อมูลการอัปเดตสถานะของคลาสธีม
ไดอะแกรมคลาสข้างต้นอธิบายเฉพาะแนวคิดรูปแบบผู้สังเกตการณ์พื้นฐานและมีข้อบกพร่องมากมาย ตัวอย่างเช่นในฐานะผู้สังเกตการณ์คุณยังสามารถสมัครรับข้อมูลบางหัวข้อ ฯลฯ ตัวอย่างต่อไปนี้จะทำการเปลี่ยนแปลงบางอย่างเพื่อใช้ตรรกะทางธุรกิจเฉพาะ
2. ตัวอย่างโหมดผู้สังเกตการณ์
เราสร้างผู้สังเกตการณ์และคลาสคลาสที่ผู้สังเกตการณ์สามารถสมัครรับข้อมูลหรือยกเลิกหัวข้อได้อย่างแข็งขัน หมวดหมู่ชุดรูปแบบได้รับการจัดการอย่างสม่ำเสมอโดยผู้จัดการธีม ต่อไปนี้เป็นแผนภาพคลาส:
เรื่อง:
หัวเรื่องสาธารณะ {// ลงทะเบียนการลงทะเบียนโมฆะสาธารณะผู้สังเกตการณ์ (Observer Observer); // ลบโมฆะสาธารณะผู้สังเกตการณ์ลบ (ผู้สังเกตการณ์ผู้สังเกตการณ์); // แจ้งผู้สังเกตการณ์ทั้งหมดโมฆะสาธารณะ NotifyobServers (); // รับข้อความที่จะเผยแพร่โดยคลาส Public Public String GetMessage ();} ConcertesUbject: MySubject Public Class ดำเนินการเรื่อง {รายการส่วนตัว <Ebserver> ผู้สังเกตการณ์; บูลีนส่วนตัวเปลี่ยนไป ข้อความสตริงส่วนตัว // การล็อควัตถุใช้เพื่ออัปเดตรายการผู้สังเกตการณ์ส่วนตัว mutex = new Object (); Public MySubject () {ผู้สังเกตการณ์ = new ArrayList <Ebserver> (); เปลี่ยน = เท็จ; } @Override Void Void Register (Observer Observer) {ถ้า (observer == null) โยน nullpointerexception ใหม่ (); // รับรองว่าจะไม่ทำซ้ำถ้า (! ผู้สังเกตการณ์. contains (ผู้สังเกตการณ์)) ผู้สังเกตการณ์. ADD (ผู้สังเกตการณ์); } @Override โมฆะสาธารณะลบ (Observer Observer) {ผู้สังเกตการณ์ Remove (Observer); } @Override โมฆะสาธารณะ NotifyObServers () {// รายการอุณหภูมิรายการ <Ebserver> tempobServers = null; ซิงโครไนซ์ (mutex) {ถ้า (เปลี่ยน) ส่งคืน; tempobservers = arraylist ใหม่ <> (this.observers); this.changed = false; } สำหรับ (observer obj: tempobservers) {obj.update (); }} // คลาสธีมเผยแพร่ข้อความใหม่โมฆะสาธารณะ makechanged (ข้อความสตริง) {system.out.println ("เรื่องทำให้เกิดการเปลี่ยนแปลง:" + ข้อความ); this.message = ข้อความ; this.changed = true; NotifyobServers (); } @Override สตริงสาธารณะ getMessage () {return this.message; -เมื่อ ConcertesUbject ทำการอัปเดตผู้สังเกตการณ์ทั้งหมดในรายการจะได้รับแจ้งและวิธีการอัปเดตผู้สังเกตการณ์จะถูกเรียกให้ใช้ตรรกะหลังจากได้รับการแจ้งเตือน หมายเหตุบล็อกการซิงโครไนซ์ใน NotifyobServers ที่นี่ ในกรณีของมัลติเธรดเพื่อหลีกเลี่ยงการเพิ่มและลบรายการผู้สังเกตการณ์โดยเธรดอื่น ๆ เมื่อเผยแพร่การแจ้งเตือนในคลาสหัวข้อจะใช้รายการชั่วคราวในบล็อกซิงโครไนซ์เพื่อรับรายการผู้สังเกตการณ์ปัจจุบัน
SubjectManagement: Theme Class Manager
การจัดการแบบคลาสสาธารณะ {// ชื่อบันทึก - แผนที่แผนที่ส่วนตัว <สตริง, หัวเรื่อง> subjectList = new hashmap <string, subject> (); โมฆะสาธารณะ addSubject (ชื่อสตริงหัวเรื่อง) {subjectList.put (ชื่อ, หัวเรื่อง); } โมฆะสาธารณะ addSubject (หัวเรื่อง) {subjectList.put (subject.getClass (). getName (), หัวเรื่อง); } Public Subject GetSubject (STRING SUBITNAME) {return subjectList.get (subjectName); } โมฆะสาธารณะ ลบ.บ. (ชื่อสตริง, หัวเรื่องหัวเรื่อง) {} โมฆะสาธารณะ ลบ.บ. (หัวเรื่อง) {} // ซิงเกิลตันส่วนตัวหัวเรื่องการจัดการ () {} การจัดการหัวเรื่องสาธารณะแบบคงที่ getInstance () } ชั้นเรียนแบบคงที่ส่วนตัว PensementManagementInstance {อินสแตนซ์การจัดการหัวเรื่องขั้นสุดท้ายคงที่ = new SubjectManagement (); -วัตถุประสงค์ของตัวจัดการหัวข้อคือการได้รับวัตถุอินสแตนซ์ของหัวข้อเมื่อผู้สังเกตการณ์สมัครรับหัวข้อ
ผู้สังเกตการณ์:
ผู้สังเกตการณ์ส่วนต่อประสานสาธารณะ {การอัปเดตโมฆะสาธารณะ (); โมฆะสาธารณะ setSubject (หัวเรื่อง);} concerteobserver: คลาสสาธารณะ myobserver ใช้ผู้สังเกตการณ์ {หัวเรื่องส่วนตัว; // รับข้อความการแจ้งเตือนจากหัวเรื่องเข้มข้น @Override โมฆะการอัปเดตสาธารณะ () {String Message = subject.getMessage (); System.out.println ("จากหัวเรื่อง" + subject.getClass (). getName () + "ข้อความ:" + ข้อความ); } @Override โมฆะสาธารณะ setSubject (หัวเรื่อง) {this.subject = subject; } // subcirbe บางเรื่องเป็นโมฆะสาธารณะสมัครสมาชิก (ชื่อเรื่องสตริง) {subjectManagement.getInstance (). getSubject (subjectName). register (นี่); } // ยกเลิกการสมัครสมาชิกโมฆะสาธารณะ cancelsubscribe (String subjectName) {subjectManagement.getInstance (). getSubject (ชื่อเรื่อง). remove (นี่); - การทดสอบ: เราเรียนวิชานามธรรมและผู้สังเกตการณ์เป็นนักเขียนและผู้อ่าน
ผู้สังเกตการณ์ชั้นเรียนสาธารณะ {นักเขียน MySubject ส่วนตัวแบบคงที่; @Beforeclass โมฆะสาธารณะคงที่ setupBeForeclass () โยนข้อยกเว้น {writer = new MySubject (); // เพิ่มนักเขียนชื่อ Linus SubjectManagement.getInstance (). AddSubject ("Linus", นักเขียน); } @Test Public Void Test () {// กำหนดผู้อ่านหลายคน myobserver reader1 = myobserver ใหม่ (); myobserver reader2 = ใหม่ myobserver (); myobserver reader3 = ใหม่ myobserver (); Reader1.SetSubject (นักเขียน); Reader2.SetSubject (นักเขียน); Reader3.SetSubject (นักเขียน); Reader1.subscribe ("Linus"); Reader2.subscribe ("Linus"); Reader3.Subscribe ("Linus"); Writer.MakeChanged ("ฉันมีการเปลี่ยนแปลงใหม่"); reader1.update (); -ข้างต้นเป็นตัวอย่างเล็ก ๆ ของรูปแบบผู้สังเกตการณ์ จะเห็นได้ว่าแต่ละคลาสคลาสจะต้องรักษารายการผู้สังเกตการณ์ที่เกี่ยวข้อง ที่นี่เราสามารถเป็นนามธรรมเพิ่มเติมตามระดับนามธรรมของหัวข้อเฉพาะทำให้การรวบรวมนี้เป็นคลาสนามธรรมเพื่อรักษารายการร่วมกัน แน่นอนการดำเนินการเฉพาะขึ้นอยู่กับตรรกะทางธุรกิจจริง
2. ผู้ฟังใน servlet
มาพูดคุยเกี่ยวกับผู้ฟังใน Servlet มาพูดคุยกันเกี่ยวกับรูปแบบอื่นของรูปแบบผู้สังเกตการณ์ - โมเดลที่ขับเคลื่อนด้วยเหตุการณ์ เช่นเดียวกับบทบาทธีมของรูปแบบผู้สังเกตการณ์ที่กล่าวถึงข้างต้นโมเดลที่ขับเคลื่อนด้วยเหตุการณ์รวมถึงแหล่งเหตุการณ์เหตุการณ์เฉพาะเหตุการณ์ผู้ฟังและผู้ฟังที่เฉพาะเจาะจง
Listener in Servlet เป็นรุ่นที่ขับเคลื่อนด้วยเหตุการณ์ทั่วไป
มีชุดของคลาสที่ขับเคลื่อนด้วยเหตุการณ์ใน JDK รวมถึงอินเทอร์เฟซผู้ฟังแบบครบวงจรและแหล่งเหตุการณ์แบบครบวงจร ซอร์สโค้ดมีดังนี้:
/*** อินเทอร์เฟซการติดแท็กที่อินเตอร์เฟสฟังเหตุการณ์ทั้งหมดต้องขยาย * @Since JDK1.1 */Public Interface EventListener {}นี่คืออินเทอร์เฟซธงและ JDK กำหนดว่าผู้ฟังทุกคนจะต้องสืบทอดอินเทอร์เฟซนี้
ระดับสาธารณะ EventObject ใช้ java.io.serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionuid = 5516075349620653480L; /*** วัตถุที่เกิดขึ้นครั้งแรก */ แหล่งกำเนิดวัตถุชั่วคราวที่ได้รับการป้องกัน /*** สร้างเหตุการณ์ต้นแบบ * * @param แหล่งที่มาวัตถุที่เกิดขึ้นครั้งแรก * @Exception unlegalArgumentException ถ้าแหล่งที่มาเป็นโมฆะ */ public eventObject (แหล่งที่มาของวัตถุ) {ถ้า (source == null) โยน unlegalargumentException ใหม่ ("แหล่งที่มา null"); this.source = แหล่งที่มา; } /*** วัตถุที่เหตุการณ์เกิดขึ้นเริ่มแรก * * @return วัตถุที่เหตุการณ์เกิดขึ้นในขั้นต้น */ วัตถุสาธารณะ getSource () {แหล่งกลับ; } /*** ส่งคืนการแสดงสตริงของเหตุการณ์นี้ * * @return a string การแสดงของ eventObject นี้ */ สตริงสาธารณะ toString () {return getClass (). getName () + "[source =" + แหล่งที่มา + "]"; -EVENOBJECT เป็นแหล่งเหตุการณ์แบบรวมที่ระบุโดย JDK คลาส EvenObject กำหนดแหล่งเหตุการณ์และวิธีการรับเพื่อรับแหล่งเหตุการณ์
มาวิเคราะห์กระบวนการดำเนินการของผู้ฟัง Servlet
1. องค์ประกอบของผู้ฟัง servlet
ปัจจุบันมีอินเทอร์เฟซผู้ฟัง 6 ประเภทสำหรับเหตุการณ์สองประเภทใน Servlets ดังแสดงในรูปด้านล่าง:
สถานการณ์ทริกเกอร์เฉพาะมีดังนี้:
2. กระบวนการทริกเกอร์ผู้ฟังที่เฉพาะเจาะจง
ลองใช้ servletrequestattributelistener เป็นตัวอย่างในการวิเคราะห์กระบวนการขับเคลื่อนเหตุการณ์ที่นี่
ก่อนอื่นเมื่อ HttpservletRequest เรียกใช้เมธอด setattrilbute จริง ๆ แล้วเรียกว่า org.apache.catalina.connector.request#วิธีการ Setattrilbute มาดูซอร์สโค้ดกันเถอะ:
โมฆะสาธารณะ setAttribute (ชื่อสตริง, ค่าวัตถุ) {... // รหัสลอจิกข้างต้นถูกละเว้น // ที่นี่ผู้ฟังจะได้รับการแจ้งเตือนว่ามีการออกแบบ (ชื่อ, ค่า, oldValue); -ต่อไปนี้เป็นซอร์สโค้ดของ NotifyattributeAsSigned (ชื่อสตริงค่าวัตถุ Object OldValue)
โมฆะส่วนตัว NotifyTributeAsSigned (ชื่อสตริง, ค่าวัตถุ, Object OldValue) {// รับวัตถุอินสแตนซ์ของผู้ฟังที่กำหนดไว้ใน WebApp จากผู้ฟังวัตถุคอนเทนเนอร์ [] = context.getApplicationEventListeners (); if ((listeners == null) || (listeners.length == 0)) {return; } บูลีนแทนที่ = (oldValue! = null); // สร้างวัตถุเหตุการณ์ที่เกี่ยวข้อง servletRequestattributeEvent event = null; if (แทนที่) {event = ใหม่ servletRequestattributeEvent (context.getServletContext (), getRequest (), ชื่อ, oldValue); } else {event = ใหม่ servletRequestattributeEvent (context.getServletContext (), getRequest (), ชื่อ, ค่า); } // ความเงียบสงบผ่านรายการผู้ฟังทั้งหมดและค้นหาผู้ฟังสำหรับเหตุการณ์ที่เกี่ยวข้องสำหรับ (int i = 0; i <listeners.length; i ++) {ถ้า (! (ผู้ฟัง [i] อินสแตนซ์ของ servletrequestattributelistener)) {ดำเนินการต่อ; } // การเรียกวิธีการฟังเพื่อใช้การฟังการฟัง servletRequestattributelistener Listener = (servletRequestattributelistener) ผู้ฟัง [i]; ลอง {ถ้า (แทนที่) {listener.attributeReplaced (เหตุการณ์); } else {listener.attributeadded (เหตุการณ์); }} catch (throwable t) {excendUts.handlethrowable (t); context.getLogger (). ข้อผิดพลาด (sm.getString ("coyoterequest.attributeEvent"), t); // ข้อผิดพลาดวาล์วจะเลือกข้อยกเว้นนี้และแสดงไปยังแอตทริบิวต์ผู้ใช้. บัท (requestDispatcher.error_exception, t); -ตัวอย่างข้างต้นแสดงให้เห็นอย่างชัดเจนว่าเรียกว่า servletrequestattributelistener อย่างไร ผู้ใช้จะต้องใช้อินเทอร์เฟซผู้ฟังเท่านั้น ผู้ฟังใน Servlets เกือบจะครอบคลุมเหตุการณ์ที่คุณสนใจตลอดวงจรชีวิตทั้งหมดของ Servlet การใช้ผู้ฟังเหล่านี้อย่างยืดหยุ่นสามารถทำให้โปรแกรมมีความยืดหยุ่นมากขึ้น
3. ตัวอย่างที่ครอบคลุม
ตัวอย่างเช่นหากคุณได้ดูภาพยนตร์ตำรวจและนักเลงของ TVB คุณจะรู้ว่าสายลับทำงานอย่างไร โดยทั่วไปตำรวจอาจมีตัวแทนสายลับหลายคนที่แอบเข้าไปในศัตรูและสอบถามเกี่ยวกับข้อมูล ตัวแทนสายลับทำงานตามคำแนะนำของผู้นำของเขาทั้งหมด ผู้นำบอกว่าเขาต้องปฏิบัติอะไร หากเวลาดำเนินการเปลี่ยนแปลงเขาจะต้องเปลี่ยนเวลาที่เขาร่วมมือกับการกระทำทันที หากผู้นำส่งตัวแทนสายลับสองตัวเพื่อบุกรุกศัตรูผู้นำจะเทียบเท่ากับธีมนามธรรม สารวัตรจางซานส่งตัวแทนสายลับสองคน Li Si และ Wan Wang Wu จางซานเทียบเท่ากับชุดรูปแบบเฉพาะและเอเจนต์สายลับเทียบเท่ากับผู้สังเกตการณ์นามธรรม ตัวแทนสายลับทั้งสองนี้คือ Li Si และ Wang Wu ซึ่งเป็นผู้สังเกตการณ์เฉพาะ การกระทำของการสอบถามเทียบเท่ากับผู้สังเกตการณ์ที่ลงทะเบียนเรื่อง จากนั้นแผนภาพคลาสนี้มีดังนี้:
การใช้ Java API เพื่อใช้คำอธิบายรหัสดังนี้:
ผู้สังเกตการณ์แพ็คเกจ; นำเข้า java.util.list; นำเข้า java.util.observable; นำเข้า java.util.observable; / ***คำอธิบาย: ตำรวจจางซาน*/ ตำรวจชั้นสาธารณะขยายเวลาที่สังเกตได้ {เวลาสตริงส่วนตัว; ตำรวจสาธารณะ (รายการ <Ebserver> รายการ) {super (); สำหรับ (ผู้สังเกตการณ์ o: รายการ) {addobserver (O); }} การเปลี่ยนแปลงโมฆะสาธารณะ (เวลาสตริง) {this.time = เวลา; setchanged (); NotifyobServers (this.time); - ผู้สังเกตการณ์แพ็คเกจ; นำเข้า java.util.observable; นำเข้า java.util.observer; / ** *คำอธิบาย: Undercover A */ Public Class UnderCovera ใช้ผู้สังเกตการณ์ {เวลาสตริงส่วนตัว; @Override การอัปเดตโมฆะสาธารณะ (สังเกต o, Object arg) {time = (String) arg; System.out.println ("เปิดเผยข้อความที่ได้รับและเวลาดำเนินการคือ:"+เวลา); - ผู้สังเกตการณ์แพ็คเกจ; นำเข้า java.util.observable; นำเข้า java.util.observer; / ** *คำอธิบาย: Undercover B */ Public Class UnderCoverB ใช้ผู้สังเกตการณ์ {เวลาสตริงส่วนตัว; @Override การอัปเดตโมฆะสาธารณะ (สังเกต o, Object arg) {time = (String) arg; System.out.println ("เปิดเผย B ได้รับข้อความและเวลาดำเนินการคือ:"+เวลา); - ผู้สังเกตการณ์แพ็คเกจ; นำเข้า java.util.arraylist; นำเข้า java.util.list; นำเข้า java.util.observer; / ***คำอธิบาย: ทดสอบ*/ ไคลเอนต์คลาสสาธารณะ {/ ***@param args*/ โมฆะคงที่สาธารณะหลัก (สตริง [] args) {undercovera o1 = undercovera ใหม่ (); Undercoverb O2 = undercoverb ใหม่ (); รายการ <Ebserver> list = new ArrayList <> (); list.add (O1); list.add (O2); เรื่องตำรวจ = ตำรวจใหม่ (รายการ); เรื่องเปลี่ยน ("02:25"); System.out.println ("========================== เนื่องจากข้อมูลที่ถูกเปิดเผยเวลาดำเนินการคือ ขั้นสูง ============================================================================= ทดสอบผลการทดสอบ:
Undercover B ได้รับข้อความและเวลาดำเนินการคือ: 02:25 Undercover A ได้รับข้อความและเวลาดำเนินการคือ: 02:25 ================= เนื่องจากการเปิดรับข้อความเวลาดำเนินการล่วงหน้า ============
4. สรุป
รูปแบบผู้สังเกตการณ์กำหนดความสัมพันธ์แบบหนึ่งต่อหลาย ๆ ระหว่างวัตถุ เมื่อสถานะของวัตถุ (ผู้สังเกตการณ์) เปลี่ยนแปลงวัตถุที่ขึ้นอยู่กับมันจะได้รับแจ้ง มันสามารถนำไปใช้กับการเผยแพร่-บันทึกการเปลี่ยนแปลงการอัปเดตในสถานการณ์ธุรกิจดังกล่าว
ผู้สังเกตการณ์ใช้วิธีการเชื่อมต่อแบบหลวม ผู้สังเกตการณ์ไม่ทราบรายละเอียดของผู้สังเกตการณ์ แต่รู้เพียงว่าผู้สังเกตการณ์ได้ใช้อินเทอร์เฟซ
โมเดลที่ขับเคลื่อนด้วยเหตุการณ์มีความยืดหยุ่นมากขึ้น แต่ก็จ่ายค่าใช้จ่ายของความซับซ้อนของระบบเพราะเราต้องปรับแต่งผู้ฟังและเหตุการณ์สำหรับแต่ละเหตุการณ์ซึ่งจะเพิ่มภาระในระบบ
แกนหลักของโมเดลผู้สังเกตการณ์คือการแยกแยะบทบาทและตำแหน่งผู้สังเกตการณ์และผู้สังเกตการณ์เป็นอันดับแรกและพวกเขาเป็นความสัมพันธ์แบบหลายต่อหนึ่ง กุญแจสำคัญในการดำเนินการคือการสร้างการเชื่อมต่อระหว่างผู้สังเกตการณ์และผู้สังเกตการณ์ ตัวอย่างเช่นมีชุดในคลาสผู้สังเกตการณ์ที่ใช้ในการจัดเก็บผู้สังเกตการณ์และผู้สังเกตการณ์ทั้งหมดจะต้องได้รับการแจ้งเตือนเมื่อสิ่งที่ตรวจพบเปลี่ยนแปลง ในคอนสตรัคเตอร์ของผู้สังเกตการณ์มันจะถูกส่งผ่านโดยผู้สังเกตการณ์และจะลงทะเบียนตัวเองในรายชื่อผู้สังเกตการณ์ที่ผู้สังเกตการณ์เป็นเจ้าของนั่นคือรายการผู้สังเกตการณ์
1. ข้อดีของโหมดผู้สังเกตการณ์:
(1) ชุดรูปแบบบทคัดย่อนั้นขึ้นอยู่กับผู้สังเกตการณ์นามธรรม (2) โหมดผู้สังเกตการณ์รองรับการสื่อสารการออกอากาศ (3) โหมดผู้สังเกตการณ์แยกเลเยอร์การสร้างข้อมูลและเลเยอร์ตอบสนอง
2. ข้อเสียของโหมดผู้สังเกตการณ์:
(1) หากมีการลงทะเบียนหัวข้อโดยผู้สังเกตการณ์จำนวนมากมันจะมีค่าใช้จ่ายสูงกว่าเพื่อแจ้งผู้สังเกตการณ์ทั้งหมด (2) หากวิธีการตอบสนองของผู้สังเกตการณ์บางคนถูกบล็อกกระบวนการแจ้งเตือนทั้งหมดจะถูกบล็อกและผู้สังเกตการณ์คนอื่นไม่สามารถแจ้งให้ทราบได้ในเวลา