Observer เลิกใช้งานใน Java 9 แล้วเราควรใช้อะไรแทน?


140

Java 9 ออกมาแล้วและObserverเลิกใช้งานแล้ว ทำไมถึงเป็นเช่นนั้น? หมายความว่าเราไม่ควรใช้รูปแบบผู้สังเกตการณ์อีกต่อไปหรือไม่?

มันจะดีถ้ารู้ว่าอะไรเป็นทางเลือกที่ดีกว่า?

คำตอบ:


110

ทำไมถึงเป็นเช่นนั้น? หมายความว่าเราไม่ควรใช้รูปแบบผู้สังเกตการณ์อีกต่อไปหรือไม่?

ตอบส่วนหลังก่อน -

ใช่มันไม่ได้หมายความว่าคุณไม่ควรดำเนินการObserverและObervables อีกต่อไป

ทำไมพวกเขาถึงเลิกใช้งาน -

พวกเขาไม่มีรูปแบบเหตุการณ์ที่สมบูรณ์เพียงพอสำหรับแอปพลิเคชัน ตัวอย่างเช่นพวกเขาสามารถสนับสนุนเฉพาะแนวคิดที่ว่ามีบางสิ่งเปลี่ยนแปลงไป แต่ไม่ได้ให้ข้อมูลเกี่ยวกับสิ่งที่เปลี่ยนแปลง

อเล็กซ์ตอบที่ทำให้มันอย่างตรงไปตรงมาว่าObserverมีจุดอ่อนทุกObservables เหมือนกัน คุณต้องใช้ตรรกะที่อ้างอิงinstanceofและโยนวัตถุให้เป็นชนิดคอนกรีตเป็นObservable.update()วิธีการ

หากต้องการเพิ่มเข้าไปมีข้อบกพร่องเช่นหนึ่งไม่สามารถทำให้Observableคลาสเป็นอนุกรมได้เนื่องจากไม่ได้ใช้Serializableอินเทอร์เฟซและสมาชิกทั้งหมดเป็นส่วนตัว

ทางเลือกที่ดีกว่านั้นคืออะไร?

ในทางกลับกันListenersมีหลายประเภทและมีวิธีการโทรกลับและไม่ต้องการการคัดเลือกนักแสดง ตามที่ @Ravi ชี้ไว้ในคำตอบของเขาคุณสามารถใช้ PropertyChangeListenerแทนได้

สำหรับส่วนที่เหลือจะ@Deprecationมีการทำเครื่องหมายด้วยเอกสารที่เหมาะสมเพื่อสำรวจแพ็คเกจอื่น ๆ ที่เชื่อมโยงในคำตอบอื่น ๆ


โปรดทราบว่าการเลิกใช้งานถูกทำเครื่องหมายด้วยการวิเคราะห์ตามที่ระบุไว้ในจดหมายนี้ -

ทุกวันนี้ใครก็ตามที่พบสิ่งเหล่านี้อาจจะกดปุ่มโดยไม่ได้ตั้งใจในขณะที่ใช้RxJavaหรือเฟรมเวิร์กรีแอคทีฟสตรีมอื่น ๆ ในกรณีนี้โดยปกติผู้ใช้จะต้องการใช้ jdk9 java.util.concurrent.FlowAPI แทนซึ่งเฟรมเวิร์กรี แอคทีฟสตรีมทั้งหมดควรเข้ากันได้ / ทำงานร่วมกันได้ภายในเวอร์ชันที่เข้ากันได้กับ jdk9 ที่วางแผนไว้

แก้ไข : นอกจากนี้ยังควรค่าแก่การกล่าวถึงว่าการเลิกใช้งาน API ไม่ได้เป็นเพียงเพราะเหตุผลข้างต้น แต่ยังไม่สามารถรักษารหัสเดิมดังกล่าวได้ตามที่กล่าวไว้ในความคิดเห็นของรายงานข้อบกพร่องบางส่วน (ลิงก์ด้านบน) ซึ่งถูกยกให้เป็น ทำเครื่องหมายการปรับปรุงการนำไปใช้ในทางใดทางหนึ่ง


3
+1. คำตอบที่ดีแม้ว่าฉันจะยังพยายามทำความเข้าใจอยู่ก็ตาม Observer ใน Java เลิกใช้งานเนื่องจากปัญหาโดยธรรมชาติของรูปแบบการออกแบบเอง (ตามที่กำหนดไว้ในหนังสือโดย GOF) หรือปัญหาของการสนับสนุนรูปแบบโดย Java หรือไม่ ในภาษา OO อื่น ๆ เช่น C #, C ++, Python รูปแบบการออกแบบผู้สังเกตการณ์มีปัญหาเช่นเดียวกับใน Java หรือไม่
ทิม

28
ความจริงที่ว่าการใช้งานบางอย่างถูกเลิกใช้ไม่ได้หมายความว่ารูปแบบ Observer นั้นมีข้อบกพร่องร้ายแรง Listenerยังเป็นนักสังเกตการณ์
chrylis -cautiouslyoptimistic-

@chrylis ขอบคุณไม่เห็นด้วยมากกว่านี้หนึ่งในเหตุผลหลักในการเลิกใช้งาน API คือการบำรุงรักษาที่แนบมาด้วยและการเปลี่ยนการใช้งานอาจทำให้โค้ดอื่นเสียหาย
Naman

ไม่เข้าใจวิธีการแจ้งเตือนพร้อมกันที่นั่น
Naman

4
@ อยากรู้อยากเห็น 95 ใช่การโทรnotifyObservers()พร้อมกัน นี่คือโค้ดเล็ตจากแชร์เดียวกันเพื่ออธิบายรายละเอียดการทำงาน
Naman

39

มีเหตุผลเพิ่มเติม:

ไม่สามารถต่อเนื่องได้ - เนื่องจาก Observable ไม่ได้ใช้ Serializable ดังนั้นคุณจึงไม่สามารถ Serialize Observable หรือคลาสย่อยของมันได้

ไม่มีความปลอดภัยของเธรด - วิธีการนี้สามารถถูกแทนที่ได้โดยคลาสย่อยและการแจ้งเตือนเหตุการณ์อาจเกิดขึ้นในคำสั่งซื้อที่แตกต่างกันและอาจเป็นไปได้ในเธรดที่แตกต่างกันซึ่งเพียงพอที่จะรบกวน "ความปลอดภัยของเธรด" ใด ๆ

ข้อเสนอน้อย -

ไม่มีรูปแบบเหตุการณ์ที่สมบูรณ์เพียงพอสำหรับแอปพลิเคชัน ตัวอย่างเช่นพวกเขาสนับสนุนเฉพาะแนวคิดที่ว่ามีการเปลี่ยนแปลง แต่ไม่ได้ให้ข้อมูลเกี่ยวกับสิ่งที่เปลี่ยนแปลง

เปิดประเด็น - เป็นที่กล่าวถึงมีจำนวนมากของประเด็นสำคัญยก (ความปลอดภัยด้าย Serializable) และส่วนใหญ่ของพวกเขามีความซับซ้อนในการแก้ไขและยังคง "ไม่คงที่" หรือไม่มีการพัฒนางานและนั่นคือเหตุผลว่าทำไมมันได้รับการเลิกใช้

ฉันอยากจะแนะนำให้อ่านคำตอบนี้ด้วยเหตุใดจึงควรเลิกใช้รูปแบบผู้สังเกตการณ์ , @Jeff ได้อธิบายเหตุผลอื่น ๆ ของการเลิกใช้งาน


เรามีทางเลือกอะไรอีกบ้าง?

คุณสามารถใช้PropertyChangeEventและPropertyChangeListenerจากjava.beansแพ็คเกจ


PropertyChangeListenerแทนที่Observerแต่ฉันควรขยาย / ปรับใช้Observableอะไรแทน?
LastStar007

อัปเดต: ฉันคิดว่าวิธีนี้คือการเพิ่ม a PropertyChangeSupportเป็นตัวแปรอินสแตนซ์ แต่ฉันขอขอบคุณสำหรับการยืนยัน
LastStar007

3
@ LastStar007 ฉันคิดว่าคุณพูดถูก ฉันพบตัวอย่างโค้ดในBaeldung.comที่ทำเช่นนั้น
Dragos Stanciu

17

เหตุใด Observer จึงเลิกใช้งานใน Java 9

ตอบ:ObservableระดับและObserverอินเตอร์เฟซที่ได้รับการคัดค้านใน Java 9 เพราะรูปแบบการจัดกิจกรรมที่สนับสนุนโดยObserverและObservableค่อนข้าง จำกัด การสั่งซื้อของการแจ้งเตือนการจัดส่งโดยObservableเป็นพลรบและการเปลี่ยนแปลงของรัฐไม่ได้อยู่ในหนึ่งสำหรับหนึ่งติดต่อกับการแจ้งเตือน

ดู Java doc https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html

รูปแบบอื่นของ Observer?

รูปแบบการออกแบบของ Observer มีทางเลือกมากมายและ Reactive Streams ก็เป็นหนึ่งในนั้น

Reactive Streams หรือ Flow API :

Flowเป็นชั้นนำในชวา 9 และมีอินเตอร์เฟซที่ 4 ความสัมพันธ์: Processor, Publisher, และSubscriberSubscription

Flow.Processor : ส่วนประกอบที่ทำหน้าที่เป็นทั้งสมาชิกและผู้เผยแพร่โฆษณา

Flow.Publisher : ผู้ผลิตรายการที่สมาชิกได้รับ

Flow.Subscriber : ผู้รับข้อความ

Flow.Subscription: การควบคุมข้อความที่เชื่อมโยงFlow.PublisherและFlow.Subscriber.

ดู Java doc https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html


10

พิจารณาว่าObservableคลาสและObserverอินเทอร์เฟซเลิกใช้แล้วในฐานะ Java 9 ตามโพสต์Observer และ Observable ของ Java เลิกใช้ใน JDK 9

รูปแบบเหตุการณ์ที่ Observer และ Observable รองรับนั้นค่อนข้าง จำกัด ลำดับของการแจ้งเตือนที่ส่งโดย Observable ไม่ได้ระบุไว้และการเปลี่ยนแปลงสถานะไม่ได้อยู่ในการโต้ตอบแบบตัวต่อตัวกับการแจ้งเตือน สำหรับรูปแบบเหตุการณ์ที่สมบูรณ์ยิ่งขึ้นให้พิจารณาใช้java.beans แพ็คเกจ สำหรับการส่งข้อความที่เชื่อถือได้และเรียงลำดับระหว่างเธรดให้พิจารณาใช้โครงสร้างข้อมูลพร้อมกันอย่างใดอย่างหนึ่งใน java.util.concurrentแพ็กเกจ สำหรับการเขียนโปรแกรมสไตล์สตรีมแบบรีแอกทีฟโปรดดู Flow API


0

ปัญหาเกิดจากการใช้งาน Java แบบบั๊กกี้ของคลาส / อินเทอร์เฟซ Java ที่ชื่อว่า Observer, Observable เป็นต้น - แต่ไม่ใช่กับ GoF Observer Pattern


1
ทำไมคำตอบ? คำถามได้รับคำตอบโดยละเอียดแล้วโดยคำนึงถึงมุมมองที่แตกต่างกันมากมาย?
Snorik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.