When Should We Use Observer and Observable

When should we use Observer and Observable?

You have a concrete example of a Student and a MessageBoard. The Student registers by adding itself to the list of Observers that want to be notified when a new Message is posted to the MessageBoard. When a Message is added to the MessageBoard, it iterates over its list of Observers and notifies them that the event occurred.

Think Twitter. When you say you want to follow someone, Twitter adds you to their follower list. When they sent a new tweet in, you see it in your input. In that case, your Twitter account is the Observer and the person you're following is the Observable.

The analogy might not be perfect, because Twitter is more likely to be a Mediator. But it illustrates the point.

What is the difference between Observable and a Subject in rxjs?

In stream programming there are two main interfaces: Observable and Observer.

Observable is for the consumer, it can be transformed and subscribed:

observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Observer is the interface which is used to feed an observable source:

observer.next(newItem)

We can create new Observable with an Observer:

var observable = Observable.create(observer => { 
observer.next('first');
observer.next('second');
...
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)

Or, we can use a Subject which implements both the Observable and the Observer interfaces:

var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('first')
source.next('second')

In Observer Design pattern, are Subject and Observable the same thing?

The Observer Design Pattern can be used whenever a subject has to be observed by one or more observers.

Observable - interface or abstract class defining the operations for attaching and de-attaching observers to the client. In the GOF book this class/interface is known as Subject.

They are essentially same.

Observer and Observable got deprecated and the reason stated is: they convey something has changed but not state what has changed, this is false?

But I was able to tell the observer that news has changed then. How that above statement is true?

The text from the issue tracker link says:

"For example, they support only the notion that something has changed, but they don't convey any information about what has changed."

In your example, the update method call tells the observer that something has changed, but not what actually changed. So, when you call setNews("Yo"), the indiaNews observer is told that newsAgency has changed. But it is NOT told what the change was. The observer can use the news argument to see the current state of the newsAgency, but there is no way to see what the state was before the change, or indeed what it was immediately after the change1.

In many use cases for Observer / Observable, the application needs to know what actually changed to trigger the update call.

THAT is the deficiency that being highlighted, and it is one of the reasons for the deprecation. The deprecation text in the javadocs list others as well:

"This class and the Observer interface have been deprecated. The event model supported by Observer and Observable is quite limited, the order of notifications delivered by Observable is unspecified, and state changes are not in one-for-one correspondence with notifications. For a richer event model, consider using the java.beans package. For reliable and ordered messaging among threads, consider using one of the concurrent data structures in the java.util.concurrent package. For reactive streams style programming, see the Flow API."


1 - Since the order of notification delivery is unspecified, the state of the observed object could have changed again by the time that the update call occurs.

Observer is deprecated in Java 9. What should we use instead of it?

Why is that? Does it mean that we shouldn't implement observer pattern anymore?

Answering the latter part first -

YES, it does mean you shouldn't implement Observer and Obervables anymore.

Why were they deprecated -

They didn't provide a rich enough event model for applications. For example, they could support only the notion that something has changed, but didn't convey any information about what has changed.

Alex's answer puts it nicely upfront that Observer has a weakness: all Observables are the same. You have to implement the logic that is based on instanceof and cast object to concrete type into Observable.update() method.

To add to it there were bugs like one could not serialize the Observable class because as it didn't implement Serializable interface and all of its members were private.

What is a better alternative to that?

On the other hand Listeners have a lot of types and they have callback methods and don't require casting. As pointed by @Ravi in his answer you can make use of PropertyChangeListener instead.

For the rest of it the @Deprecation has been marked with proper documentation to explore other packages as linked in other answers as well.


Note that the deprecation was also marked with an analysis as stated in this mail -

These days, anyone encountering these is probably hitting them by
mistake while using RxJava or other reactive-stream frameworks. In
which case, users will normally want to instead use the jdk9
java.util.concurrent.Flow APIs that all reactive-streams frameworks
should be compatible/interoperable within their planned upcoming
jdk9-compatible versions.

Edit: It's also worth mentioning that the deprecation of the APIs is not primarily just because of the above reason, but also being unable to maintain such legacy code as mentioned in comments of a few of the bug reports (linked above) which were raised to mark an improvement in its implementation in one or another way.

RxJS Is Observer and Subscriber the same thing?

Observer

const observer = {
next: v => /* code for next callback*/,
error: err => /* code for error callback*/,
complete: () => /* code for completion callback*/
}

Subscription

const subscription = {
unsubscribe: () => /* code for unsubscribe callback */
}

Observable

const observable1 = from([1,2,3,4,5]);
const observable2 = of(1,2,3,4,5);
const observable3 = new Observable(observer => {
observer.next(1);
observer.next(2);
observer.next(3);
observer.next(4);
observer.next(5);
observer.complete();

return { // return a subscription
unsubscribe: () => /* code for unsubscribe callback */
};
});

Subscribe and use the Returned Subscription

// Store a subscription 
const subscription = observable3.subscribe(observer);
// Invoke the unsubscribe callback defined by the observable.
subscription.unsubscribe();

Okay. Then What is a Subscriber?

[Subscriber] Implements the Observer interface and extends the Subscription class. While the Observer is the public API for consuming the values of an Observable, all Observers get converted to a Subscriber... Subscriber is a common type in RxJS, and crucial for implementing operators, but it is rarely used as a public API.

Are observers and subscribers the same thing? Kind of, yes? Depends on how concretely you ask the question.

Consider this:

observable3.subscribe({
next: v => /* code for next callback */
});

obsevable3.subscribe(
v => /* code for next callback */
);

The first is an object with only one observer property defined. The second is simply a lambda function. They both end up generating basically the same subscriber.

Rxjs observable versus observer 'semantics'

Observable-Observer pattern is a Push mechanism, means that it is the mission of Observable to notify Observer. Observable needs a reference to Observer to notify it about new emitions. Observable callbacks such as onNext and onError are the bridge between Observable-Observer so such callbacks exists in Observer and Observable will call them.

What are the differences between using a Subject and an Observable, and what are the uses for each?

A Subject is both Observable and Observer at the same time. That makes it so tempting to use, because you get a reference to an Observer that you can pass around in your code and emit items from wherever you want. However, that increases the error-proneness of your code by a lot, as you switch from a declarative definition of your Observable to a imperative one.

Generally speaking, you should use Observable creation functions (of, from, create) wherever possible. I'd say most cases can be solved without Subjects. There is a steep learning-curve though, as you must get to know most of the Observable creation functions in order to follow that pattern.

Subject might come more natural to developers who are used to code imperatively (that is: with a script language like JS), as it kind of resembles a simple wrapper object for a callback function. And one might ask, why is there a Subject anyway if its not desirable.

According to this article, Subjects are to be used in one case only:

To generate a hot observable imperatively and statefully, without any direct external source.

In short, that means: Use Subject when you don't have any external source (like an Observable, Promise or Event) and need to multicast the state of a class from inside a function. You shouldn't expose that Subject to others, though!

I suggest reading this article to you, it will clear up things.



Related Topics



Leave a reply



Submit