Sự khác biệt giữa Người quan sát và Người đăng ký là gì?


83

Tôi đang cố gắng giải mã hàm sau:

Subscription getCar(id, Observer<Car> observer) {
    return getCarDetails(id, new Observer<CarDetails> {
                             @Override
                             onNext(CarDetails details) {           
                                 observer.onNext(details.getCar());
                             } });
}

Tôi có một phần giới thiệu tốt về rxjava từ http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ nhưng nó chỉ đề cập đến Observer, nói rằng bạn sẽ sử dụng Người đăng ký hầu hết thời gian đến các mặt hàng tiêu dùng được phát ra từ một Có thể quan sát.

Ai đó có thể giải thích cho tôi được không

  1. Người quan sát là gì?
  2. Người quan sát khác với người đăng ký như thế nào?
  3. Đoạn mã trên làm gì?

Javadoc làm cho nó có vẻ giống như một người đăng ký. Javadoc dành cho người đăng ký cho biết nó triển khai trình quan sát và đăng ký. Tôi rất bối rối.


Đó là mô hình Người quan sát so với xuất bản / đăng ký . Chúng tương tự nhau, nhưng có sự khác biệt tinh tế.
Sean Patrick Floyd

4
@SeanPatrickFloyd: Bạn có thể giải thích sự khác biệt không?
user541686,

Biến 'chi tiết' là gì?
Marian Paździoch

Câu trả lời:


63

ĐÃ CHỈNH SỬA : với nhận xét của @ Alrid

tl; dr

public abstract class Subscriber<T> implements Observer<T>, Subscription

Vì vậy, Người đăng ký là một triển khai của Người quan sát , với ngữ nghĩa bổ sung về đăng ký (nó thiên về hủy đăng ký). Đoạn mã trong câu hỏi của bạn chỉ cho thấy rằng nó vượt qua Observergiao diện, thay vì thực hiện (thực hành lập trình thông thường).

Ngoài ra, mã này trả về a Subscription, đó có thể là do tác giả của mã này nghĩ rằng máy khách chỉ nên có quyền truy cập vào Subscriptioncác phương thức, không có quyền truy cập vào các phần tử được tạo ra bởi trình quan sát. Đó có thể là lỗi của lập trình viên.

câu chuyện dài

Thực sự bạn nên đọc nội dung của trang web này (hoặc sách): http://www.introtorx.com Đó là về Rx.Net, nhưng các khái niệm rất giống nhau, chúng được tạo ra bởi Erik Meijer và những người thực hiện RxJava đã làm theo chúng ( nếu áp dụng cho ngôn ngữ Java).

Trang này sẽ khiến bạn quan tâm (nó là chương thứ hai): KeyTypes

Ở đây, bạn sẽ đọc những đoạn đầu tiên:

Có hai loại chính cần hiểu khi làm việc với Rx và một tập hợp con các loại bổ trợ sẽ giúp bạn học Rx hiệu quả hơn. IObserver và IObservable tạo thành các khối xây dựng cơ bản cho Rx, trong khi việc triển khai ISubject giảm bớt đường cong học tập cho các nhà phát triển mới làm quen với Rx.

...

Về cơ bản Rx được xây dựng dựa trên nền tảng của mẫu Observer. .NET đã tiết lộ một số cách khác để triển khai mẫu Observer chẳng hạn như đại biểu hoặc sự kiện đa hướng (thường là đại biểu đa hướng).

Ngay cả khi các loại / API khác nhau một chút, bạn sẽ học được rất nhiều điều với cuốn sách này, có thể là nhiều hơn so với một số blog.

Điều này có cuốn sách không nói ( ... bởi vì nó là trong việc thực hiện RxJava )

Nhà phát triển chính RxJava tại thời điểm này đã giới thiệu một biến thể nhỏ (xem PR # 792 ) cho phép phân biệt hai loại hợp đồng:

  • thông báo -> Observer
  • (bỏ) đăng ký -> Subscription

Thay đổi này cho phép thể hiện / phân tách tốt hơn những mối quan tâm này của các lớp triển khai của thư viện RxJava.

Tuy nhiên, với tư cách là người dùng thư viện, việc sử dụng các triển khai thực tế của thư viện RxJava phải đủ tốt.

Việc triển khai một thuê bao đòi hỏi nhiều kiến ​​thức, công việc và sự cẩn thận hơn, thực sự ngữ nghĩa của đăng ký rất quan trọng tùy thuộc vào loại nguồn có thể quan sát được (Nóng hay lạnh? Tạo đắt tiền?)


Việc để lộ Subscriberchứ không phải Observertrong những trường hợp như trên sẽ không ảnh hưởng đến mã trong hầu hết các trường hợp, nhưng nó không phải là mục đích sử dụng cho nó trừ khi những ngữ nghĩa hủy đăng ký đó là cần thiết. Nhưng cuối cùng việc thực hiện a Subscriber, và có thể liên quan đến việc rơi vào một số cạm bẫy như:

  1. dành tài nguyên cho chức năng bạn sẽ không sử dụng
  2. không thể kế thừa từ lớp khác
  3. viết sai mã hủy đăng ký
  4. sao chép / dán mã một mã không chính xác hoặc mã đúng được viết cho một ngữ cảnh khác

1
Trong 2.x Người quan sát được sử dụng để đăng ký Người có thể quan sát và Người đăng ký được sử dụng để đăng ký Người có thể lưu chuyển, Người đăng ký không còn triển khai Người quan sát nữa, github.com/ReactiveX/RxJava/issues/4515
sarvesh chavan

39

(Chỉnh sửa: Điều này dường như chỉ đúng với RxJava 1.)

  1. An Observerlà một đối tượng có thể lấy dữ liệu từ một nguồn dữ liệu (an Observable). Nguồn dữ liệu đẩy dữ liệu đến nó bằng cách gọi người quan sát onNext().

  2. A Subscriberlà một Observercũng có thể hủy đăng ký khỏi nguồn dữ liệu đó (thông qua Subscriptiongiao diện).

  3. Các getCar()chức năng đang cố gắng quay trở lại xe, nhưng không có phương pháp trực tiếp để làm điều đó. Nhưng có một chức năng lấy thông tin chi tiết về xe ( getCarDetails()) sẽ gọi một người quan sát với tất cả các chi tiết xe. Vì vậy, nó gọi hàm đó và chuyển nó cho một người quan sát, khi nó nhận được dữ liệu, sẽ lấy dữ liệu xe từ các chi tiết và chuyển nó cho người quan sát của chính nó.


2
Điều này không đúng với RxJava 2, người đăng ký và người quan sát là hai giao diện hoàn toàn khác nhau. Không mở rộng cái kia
FRR

19

Trong RxJava 2 org.reactivestreams.Subscriber là một giao diện tuân theo đặc tả của Reactive Streams .

Sự khác biệt chính Observablelà mớiSubscriber hỗ trợ áp suất ngược mới.

Observerđược đăng ký ObservableSubscriberđược đăng ký Flowable(thực hiệnorg.reactivestreams.Publisher ).

Xem mô tả chi tiết tại đây .


3

Cũng trong RxJava2 , nếu bạn muốn có thể hủy đăng ký, bạn nên sử dụng ResourceObserverfor ObservableResourceSubscriberforFlowable .

Kiểm tra câu hỏi này

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.