Observer không được dùng trong Java 9. Chúng ta nên sử dụng cái gì thay vì nó?


133

Java 9 ra đời và Observerđã bị phản đối. Tại sao vậy? Có nghĩa là chúng ta không nên thực hiện mô hình quan sát nữa?

Nó sẽ là tốt để biết những gì là một thay thế tốt hơn?

Câu trả lời:


104

Tại sao vậy? Có nghĩa là chúng ta không nên thực hiện mô hình quan sát nữa?

Trả lời phần sau trước -

, điều đó có nghĩa là bạn không nên thực hiệnObserverObervables nữa.

Tại sao họ không được tán thành -

Họ đã không cung cấp một mô hình sự kiện đủ phong phú cho các ứng dụng. Ví dụ, họ chỉ có thể hỗ trợ khái niệm rằng một cái gì đó đã thay đổi, nhưng không truyền đạt bất kỳ thông tin nào về những gì đã thay đổi.

Câu trả lời của Alex đưa ra câu trả lời độc đáo Observercó một điểm yếu: tất cả Observableđều giống nhau . Bạn phải triển khai logic dựa trên instanceofvà chuyển đối tượng thành kiểu cụ thể thành Observable.update()phương thức.

Để thêm vào đó, có một số lỗi như người ta không thể tuần tự hóaObservable lớp vì nó không triển khai Serializablegiao diện và tất cả các thành viên của nó là riêng tư.

Một thay thế tốt hơn cho điều đó là gì?

Mặt khác, Listenerscó rất nhiều loại và chúng có phương thức gọi lại và không yêu cầu truyền. Như được chỉ ra bởi @Ravi trong câu trả lời của anh ấy, bạn có thể sử dụng PropertyChangeListenerthay thế.

Đối với phần còn lại của nó, nó @Deprecationđã được đánh dấu bằng tài liệu thích hợp để khám phá các gói khác như được liên kết trong các câu trả lời khác.


Lưu ý rằng sự phản đối cũng được đánh dấu bằng một phân tích như được nêu trong thư này -

Ngày nay, bất cứ ai gặp phải những điều này đều có thể đánh nhầm họ trong khi sử dụng RxJavahoặc các khung luồng phản ứng khác. Trong trường hợp đó, người dùng thường muốn sử dụng java.util.concurrent.FlowAPI jdk9 mà tất cả các khung luồng phản ứng phải tương thích / tương thích trong các phiên bản tương thích jdk9 sắp tới của họ.

Chỉnh sửa : Điều đáng nói là sự phản đối của các API không chỉ chủ yếu vì lý do trên mà còn không thể duy trì mã kế thừa như đã đề cập trong các nhận xét về một số báo cáo lỗi (được liên kết ở trên) đánh dấu một sự cải tiến trong việc thực hiện nó theo cách này hay cách khác.


3
+1. Câu trả lời tốt, mặc dù tôi vẫn đang cố gắng để hiểu nó. Có phải Observer trong Java không được chấp nhận vì một số vấn đề cố hữu của chính mẫu thiết kế (như được định nghĩa trong cuốn sách của GOF) hoặc vấn đề hỗ trợ cho mẫu của Java? Trong các ngôn ngữ OO khác, chẳng hạn như C #, C ++, Python, mẫu thiết kế quan sát viên cũng có vấn đề tương tự như trong Java?
Tim

25
Việc một triển khai cụ thể không được chấp nhận không có nghĩa là mẫu Observer bị thiếu sót nghiêm trọng. Listenercũng là một Người quan sát.
chrylis -cautiouslyoptimistic-

@chrylis Cảm ơn, không thể đồng ý nhiều hơn, một trong những lý do chính để loại bỏ API cũng là bảo trì kèm theo và việc thay đổi triển khai của nó có thể đã phá vỡ mã khác.
Naman

@ tò mò95 Không thể hiểu cách thông báo đồng thời ở đó.
Naman

4
@ tò mò95 Có gọi notifyObservers()là đồng thời. Đây là một codelet từ cùng được chia sẻ để giải thích chi tiết chức năng của nó.
Naman

37

Vâng, nó không được dùng trong Java 9 . Và, chúng ta không thể thực hiện mô hình quan sát nữa.


Tại sao vậy?

Có nhiều lý do:

Không tuần tự hóa - Vì, Observable không thực hiện Nối tiếp. Vì vậy, bạn không thể tuần tự hóa có thể quan sát được cả lớp con của nó.

Không an toàn luồng - Các phương thức có thể bị ghi đè bởi các lớp con của nó và thông báo sự kiện có thể xảy ra theo các thứ tự khác nhau và có thể trên các luồng khác nhau, đủ để phá vỡ bất kỳ "an toàn luồng" nào.

Ít để cung cấp -

Họ không cung cấp một mô hình sự kiện đủ phong phú cho các ứng dụng. Ví dụ, họ chỉ ủng hộ quan niệm rằng có gì đó đã thay đổi, nhưng họ không truyền đạt bất kỳ thông tin nào về những gì đã thay đổi

Các vấn đề mở - Như đã đề cập, có rất nhiều vấn đề lớn được nêu ra (an toàn luồng, tuần tự hóa) và hầu hết chúng có các phức tạp để khắc phục và vẫn "không sửa" hoặc Không phát triển tích cực , và đó là lý do tại sao nó bị từ chối .

Tôi cũng khuyên bạn nên đọc câu trả lời này Tại sao mẫu quan sát viên không được dùng nữa? , @Jeff đã giải thích các lý do khác cho sự phản đối.


Vì vậy, những gì chúng ta có thay thế?

Bạn có thể sử dụng PropertyChangeEventPropertyChangeListenertừ java.beansgói.


PropertyChangeListenerthay thế Observer, nhưng tôi nên mở rộng / thực hiện những gì thay thế Observable?
Laststar007

Cập nhật: Tôi nghĩ rằng cách tiếp cận là thêm một PropertyChangeSupportbiến thể hiện, nhưng tôi đánh giá cao một xác nhận.
Laststar007

3
@ LastStar007 Tôi nghĩ bạn đúng. Tôi đã tìm thấy một mẫu mã trên Baeldung.com chỉ có thế.
Dragos Stanciu

13

Tại sao Observer không được dùng trong Java 9?

Ans: Các Observablelớp và các Observergiao diện đã được tán trong Java 9 vì mô hình sự kiện được hỗ trợ bởi ObserverObservableđược khá hạn chế, trình tự thông báo cung cấp bởi Observablelà không xác định, và thay đổi trạng thái đang không ở trong một cho-một thư từ với thông báo.

Xem tài liệu Java https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html

Thay thế mô hình quan sát?

Có nhiều lựa chọn thay thế của mẫu thiết kế Observer và Reactive Streams là một trong số đó.

Luồng phản ứng hoặc API luồng :

Flowlà một lớp giới thiệu trong Java 9 và có 4 giao diện liên quan đến nhau: Processor, Publisher, SubscriberSubscription.

Flow.Processor : Một thành phần hoạt động như cả Người đăng ký và Nhà xuất bản.

Flow.Publisher : Một nhà sản xuất các mặt hàng nhận được bởi Người đăng ký.

Flow.Subscriber : Một người nhận tin nhắn.

Flow.Subscription: Điều khiển tin nhắn liên kết a Flow.PublisherFlow.Subscriber.

Xem tài liệu Java https://docs.oracle.com/javase/9/docs/api/java/util/concản/Flow.html


7

Xem xét rằng Observablelớp và Observergiao diện đã không được dùng nữa kể từ Java 9. Theo như bài viết Người quan sát và Quan sát của Java bị phản đối trong JDK 9

Mô hình sự kiện được Observer và Observable hỗ trợ khá hạn chế, thứ tự thông báo được phân phối bởi Observable là không xác định và các thay đổi trạng thái không tương ứng với một thông báo. Đối với một mô hình sự kiện phong phú hơn, hãy xem xét sử dụng java.beans gói. Để nhắn tin đáng tin cậy và có trật tự giữa các luồng, hãy xem xét sử dụng một trong các cấu trúc dữ liệu đồng thời trong java.util.concurrentgói. Để lập trình kiểu luồng phản ứng, hãy xem API Flow.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.