Pub/Sub Vs Observer Vs Reactive

5.8k Views Asked by At

When I have used Pub/Sub pattern frameworks like MVVMLight before, I have seen that the subscriber's calls are handled synchronously. From a scalability point of view, does a reactive framework like Rx help scalability where the pub and sub are completely decoupled and scalable? Which pattern helps scalability?

2

There are 2 best solutions below

0
On

The reactive programming paradigm is often presented in object-oriented languages as an extension of the Observer design pattern. You can also compare the main reactive streams pattern with the familiar Iterator design pattern, as there is a duality to the Iterable-Iterator pair in all of these libraries. One major difference is that, while an Iterator is pull-based, reactive streams are push-based.

Using an iterator is an imperative programming pattern, even though the method of accessing values is solely the responsibility of the Iterable. Indeed, it is up to the developer to choose when to access the next() item in the sequence. In reactive streams, the equivalent of the above pair is Publisher-Subscriber. But it is the Publisher that notifies the Subscriber of newly available values as they come, and this push aspect is the key to being reactive. Also, operations applied to pushed values are expressed declaratively rather than imperatively: The programmer expresses the logic of the computation rather than describing its exact control flow.

Source: https://projectreactor.io/docs/core/release/reference/#intro-reactive

0
On

I don't know the specifics of MVVMLight, but in general the Pub/Sub is a pattern, where:

  • Publishers and subscribers don't know about each other. They only know about a broker, where they publish/consume messages.
  • As a result, the publication and consumption of messages is done asynchronously and is completely decoupled. This means that the publication/consumption side can be scaled independently and in case of failures of one part, the other part is able to keep working.

Now, reactive programming is a pattern used to model changes and their propagation across multiple actors. As such, it's not so much concerned with implementation details, but more focused on providing an abstract, declarative interface, which makes it easier to work with streams of events and perform processing on top of them. Straight from ReactiveX's documentation:

ReactiveX is not biased toward some particular source of concurrency or asynchronicity. Observables can be implemented using thread-pools, event loops, non-blocking I/O, actors (such as from Akka), or whatever implementation suits your needs, your style, or your expertise. Client code treats all of its interactions with Observables as asynchronous, whether your underlying implementation is blocking or non-blocking and however you choose to implement it.

So, the decoupling/scalability will be mainly dependent on the implementation used underneath; the main benefit of the framework is mainly the abstract, declarative interface provided.

Regarding the observer pattern (which is mentioned in the question's title): it's a rather low-level primitive that can be used to achieve the same goal, but can probably lead to a much more complex codebase. For more details on the pitfalls of observer pattern when compared with more abstract reactive frameworks, you can read the following paper:

Deprecating the Observer pattern with Scala.React