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
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:
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.
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
Pull Mechanism
References
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();
}
}
The observer pattern uses push since the observable object push notifications to its subscribers.
Push vs Pull (in web mostly): Push - the server sends(push) notifications to clients, this means it needs keep tracking on their address (URI) or in the more general case their reference.
Pull - the client is responsible for requesting fresh data from the server.
The pattern is not only for Web and is used all over, for example in desktop applications.