When should we use Observer and Observable? When should we use Observer and Observable? java java

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.


In very simple terms (because the other answers are referring you to all the official design patterns anyway, so look at them for further details):

If you want to have a class which is monitored by other classes in the ecosystem of your program you say that you want the class to be observable. I.e. there might be some changes in its state which you would want to broadcast to the rest of the program.

Now, to do this we have to call some kind of method. We don't want the Observable class to be tightly coupled with the classes that are interested in observing it. It doesn't care who it is as long as it fulfils certain criteria. (Imagine it is a radio station, it doesn't care who is listening as long as they have an FM radio tuned on their frequency). To achieve that we use an interface, referred to as the Observer.

Therefore, the Observable class will have a list of Observers (i.e. instances implementing the Observer interface methods you might have). Whenever it wants to broadcast something, it just calls the method on all the observers, one after the other.

The last thing to close the puzzle is how will the Observable class know who is interested?So the Observable class must offer some mechanism to allow Observers to register their interest. A method such as addObserver(Observer o) internally adds the Observer to the list of observers, so that when something important happens, it loops through the list and calls the respective notification method of the Observer interface of each instance in the list.

It might be that in the interview they did not ask you explicitly about the java.util.Observer and java.util.Observable but about the generic concept. The concept is a design pattern, which Java happens to provide support for directly out of the box to help you implement it quickly when you need it. So I would suggest that you understand the concept rather than the actual methods/classes (which you can look up when you need them).

UPDATE

In response to your comment, the actual java.util.Observable class offers the following facilities:

  1. Maintaining a list of java.util.Observer instances. New instances interested in being notified can be added through addObserver(Observer o), and removed through deleteObserver(Observer o).

  2. Maintaining an internal state, specifying whether the object has changed since the last notification to the observers. This is useful because it separates the part where you say that the Observable has changed, from the part where you notify the changes. (E.g. Its useful if you have multiple changes happening and you only want to notify at the end of the process rather than at each small step). This is done through setChanged(). So you just call it when you changed something to the Observable and you want the rest of the Observers to eventually know about it.

  3. Notifying all observers that the specific Observable has changed state. This is done through notifyObservers(). This checks if the object has actually changed (i.e. a call to setChanged() was made) before proceeding with the notification. There are 2 versions, one with no arguments and one with an Object argument, in case you want to pass some extra information with the notification. Internally what happens is that it just iterates through the list of Observer instances and calls the update(Observable o, Object arg) method for each of them. This tells the Observer which was the Observable object that changed (you could be observing more than one), and the extra Object arg to potentially carry some extra information (passed through notifyObservers().


Definition

Observer pattern is used when there is one to many relationship between objects such as if one object is modified, its dependent objects are to be notified automatically and corresponding changes are done to all dependent objects.

Examples

  1. Let's say, your permanent address is changed then you need to notify passport authority and pan card authority. So here passport authority and pan card authority are observers and You are a subject.

  2. On Facebook also, If you subscribe to someone then whenever new updates happen then you will be notified.

When to use it:

  1. When one object changes its state, then all other dependents object must automatically change their state to maintain consistency

  2. When the subject doesn't know about the number of observers it has.

  3. When an object should be able to notify other objects without knowing who objects are.

Step 1

Create Subject class.

Subject.java

  import java.util.ArrayList;  import java.util.List;  public class Subject {  private List<Observer> observers         = new ArrayList<Observer>();  private int state;  public int getState() {    return state;  } public void setState(int state) {   this.state = state;   notifyAllObservers(); }   public void attach(Observer observer){     observers.add(observer);          }  public void notifyAllObservers(){    for (Observer observer : observers) {     observer.update();  }}   

}

Step 2

Create Observer class.

Observer.java

public abstract class Observer {   protected Subject subject;   public abstract void update();}

Step 3

Create concrete observer classes

BinaryObserver.java

public class BinaryObserver extends Observer{  public BinaryObserver(Subject subject){     this.subject = subject;     this.subject.attach(this);  }  @Override  public void update() {     System.out.println( "Binary String: "      + Integer.toBinaryString( subject.getState() ) );   }

}

OctalObserver.java

public class OctalObserver extends Observer{   public OctalObserver(Subject subject){     this.subject = subject;    this.subject.attach(this); }  @Override  public void update() {    System.out.println( "Octal String: "     + Integer.toOctalString( subject.getState() ) );   }

}

HexaObserver.java

public class HexaObserver extends Observer{  public HexaObserver(Subject subject){    this.subject = subject;    this.subject.attach(this); }  @Override  public void update() {     System.out.println( "Hex String: "     + Integer.toHexString( subject.getState() ).toUpperCase() ); }

}

Step 4

Use Subject and concrete observer objects.

ObserverPatternDemo.java

 public class ObserverPatternDemo {    public static void main(String[] args) {       Subject subject = new Subject();       new HexaObserver(subject);       new OctalObserver(subject);       new BinaryObserver(subject);       System.out.println("First state change: 15");           subject.setState(15);       System.out.println("Second state change: 10");          subject.setState(10); }

}

Step 5

Verify the output.

First state change: 15

Hex String: F

Octal String: 17

Binary String: 1111

Second state change: 10

Hex String: A

Octal String: 12

Binary String: 1010