Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push, pull mechanism observer pattern

At the moment I'm studying design patterns and I've come to a part where I'm confused whether the observer pattern makes use of the push mechanism or does it make use of the pull mechanism?

I've read different implementations of this and can't really establish which one is correct.

Also, I'd like to know three straight forward advantages of the push model towards the pull model. I guess one of them is that the push model is less coupled then the pull model?

like image 716
Liusara Avatar asked Jan 10 '16 13:01

Liusara


2 Answers

Observer Pattern in detail (with the focus on questions asked)


  • Definition : The Observer Pattern defines a one-to-many dependency between the objects so that when one object changes state, all of its dependents are notified and updated automatically

  • 3 things to focus:

    1. Observable object - The object being observed.
    2. Observer objects - The objects that observe the observable object
    3. Communication Mechanism - Pull or Push Mechanism

At the moment i'm studying design patterns and i've came to a part where i'm confused whether the observer pattern makes use of the push mechanism or does it makes use of the pull mechanism ?

Confusion might be because you are literary going by name - Pull or Push.

Please note that in both mechanisms, it is always the responsibility of Observable object to notify all the subscribed observers, but the difference lies whether [Push->]the observer get the exact data it wants or [Pull->] it get the data wrapped in some object (mostly Observable object) & it has to extract the required data from it.

  • Push -> Observer get the required data directly
  • Pull -> Observer get the data wrapped in an object and it needs to extract that.

I've read different implementations of this and can't really establish which one is correct.

It is not the question of correction here, actually both will work absolutely fine in any situation. It's just which is best suited to a particular scenario/situation which can be easily analysed if we see following details for both the mechanism.

Also i'd like to know three straight forward advantages of the push model towards the pull model. I guess one of them is that the push model is less coupled then the pull model ?

I may not be able to provide 3 advantages, but let me try if I can give you a clear picture of where to use what by using use-case examples:

  • Push Mechanism

    • This is purely the Observable's responsibility, Observer just need to make sure they have put required code in their update methods.
    • Advantages
      • The main advantage of the 'push' model is lower coupling between the observer and the subject.
        • Observable & Observer both are interfaces/abstract classes which is actually a design principle - Program to interface or supertypes
    • Disadvantage
      • Less flexibility : As Observable needs to send the required data to the Observer and it would become messy if we have say 1000 observers and most of them require different types of data.
    • Use-Case
      • It should be used when there are max 2-3 different types of Observers (different types means observer require different data) or all observers require same type of data.
      • Like token systems in a bank
        • In this all observers (different LEDs) just need one notification the list of updated waiting token numbers, so may better be implemented in this way as compared to Pull Mechanism.
  • Pull Mechanism

    • In pull mechanism as well, it is the Observable's responsibility to notify all observer that something has been changed, but this time Observable shares the whole object which has the changes, some observers might not require the complete object, so Observers just need extract the required details from that complete project in their update methods.
    • Advantages
      • The advantage of this is more flexibility.
        • Each observer can decide for itself what to query, without relying on the subject to send the correct (only required) information.
    • Disadvantage
      • The observers would have to know things about the subject in order to query the right information from the shared complete object.
    • Use-Case
      • It should be used when there are more than 2-3 different types of Observers (different types means observer require different data)
      • Like publishing of FX Rates by any foreign exchange rates provider for different investment banks
        • In this Some banks just deals with only INR, some others only GBP etc. so it should be implemented using Pull mechanism as compared to Push mechanism.

References

  • Head-First book for design Patterns
  • https://softwareengineering.stackexchange.com/questions/253398/the-observer-pattern-using-the-pulling-mechanism?newreg=999c28a6a1f6499783fbe56eb97fa8ec
  • https://dzone.com/articles/observer-pattern
like image 200
amandeep1991 Avatar answered Sep 18 '22 06:09

amandeep1991


This is an example code that uses the "PULL" mode as explained above Observers could get different types of data (not implemented in this case).

import java.io.*;
import java.util.*;

 interface Observer{
    public void update();
}

 interface Observable {
    public void notifyAll() throws Exception;
    public void notify(Observer o) throws Exception;
}
class Suscriber implements Observer {
    String id;
    Subject subject;
    boolean registered = false;
    Double data = 0.0;
    public Suscriber(String id,Subject sub){
        this.id = id;
        subject = sub;    

        subject.register(this);
        registered = true;
    }

    public void update() {
        if(registered){
            data = subject.getData();
        }
        display();
    }

    void display(){
        System.out.println("Suscriber:" + id + " updated");
        System.out.println("Current DATA: " + data);
    }
}
class Subject implements Observable{
    private List<Observer> observers = new ArrayList<Observer>();
    private Double data = 0.0;

    public void register(Observer o){
        observers.add(o);
    }
    public void unregister(Observer o){
        int i =    observers.indexOf(o);

        observers.remove(i);
    }

    public void notify(Observer o) throws Exception{
          o.update();
    }

    public void notifyAll() throws Exception {
        for(Observer o:observers)
          this.notify(o);
    }

    public void computeMetrics(){
        try{
        long bunch = System.currentTimeMillis()/2;
        data = data + new Double(bunch);
        this.notifyAll();
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public Double getData() {
        return this.data;
    }
}

class ObserverTestDrive {
    public static void main (String[] args) {

        Subject subject = new Subject();

        long transmission = 10000;

        Suscriber norths = new Suscriber("NorthStation",subject);
        Suscriber wests = new Suscriber("WestStation",subject);
        Suscriber souths = new Suscriber("SouthStation",subject);

        for(int i=0;i<transmission;i++)
            subject.computeMetrics();










    }
}
like image 33
davidza5 Avatar answered Sep 21 '22 06:09

davidza5