[java] When should we use Observer and Observable?

An interviewer asked me:

What is Observer and Observable and when should we use them?

I wasn't aware of these terms, so when I got back home and started Googling about Observer and Observable, I found some points from different resources:

1) Observable is a class and Observer is an interface.

2) The Observable class maintains a list of Observers.

3) When an Observable object is updated, it invokes the update() method of each of its Observers to notify that, it is changed.

I found this example:

import java.util.Observable;
import java.util.Observer;

class MessageBoard extends Observable
{
    public void changeMessage(String message) 
    {
        setChanged();
        notifyObservers(message);
    }
}

class Student implements Observer 
{
    @Override
    public void update(Observable o, Object arg) 
    {
        System.out.println("Message board changed: " + arg);
    }
}

public class MessageBoardTest 
{
    public static void main(String[] args) 
    {
        MessageBoard board = new MessageBoard();
        Student bob = new Student();
        Student joe = new Student();
        board.addObserver(bob);
        board.addObserver(joe);
        board.changeMessage("More Homework!");
    }
}

But I don't understand why we need Observer and Observable? What are the setChanged() and notifyObservers(message) methods for?

The answer is


Observer a.k.a callback is registered at Observable.

It is used for informing e.g. about events that happened at some point of time. It is widely used in Swing, Ajax, GWT for dispatching operations on e.g. UI events (button clicks, textfields changed etc).

In Swing you find methods like addXXXListener(Listener l), in GWT you have (Async)callbacks.

As list of observers is dynamic, observers can register and unregister during runtime. It is also a good way do decouple observable from observers, as interfaces are used.


I have written a short description of the observer pattern here: http://www.devcodenote.com/2015/04/design-patterns-observer-pattern.html

A snippet from the post:

Observer Pattern : It essentially establishes a one-to-many relationship between objects and has a loosely coupled design between interdependent objects.

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

Consider a feed notification service for example. Subscription models are the best to understand the observer pattern.


Since Java9, both interfaces are deprecated, meaning you should not use them anymore. See Observer is deprecated in Java 9. What should we use instead of it?

However, you might still get interview questions about them...


They are parts of the Observer design pattern. Usually one or more obervers get informed about changes in one observable. It's a notifcation that "something" happened, where you as a programmer can define what "something" means.

When using this pattern, you decouple the both entities from each another - the observers become pluggable.


"I tried to figure out, why exactly we need Observer and Observable"

As previous answers already stated, they provide means of subscribing an observer to receive automatic notifications of an observable.

One example application where this may be useful is in data binding, let's say you have some UI that edits some data, and you want the UI to react when the data is updated, you can make your data observable, and subscribe your UI components to the data

Knockout.js is a MVVM javascript framework that has a great getting started tutorial, to see more observables in action I really recommend going through the tutorial. http://learn.knockoutjs.com/

I also found this article in Visual Studio 2008 start page (The Observer Pattern is the foundation of Model View Controller (MVC) development) http://visualstudiomagazine.com/articles/2013/08/14/the-observer-pattern-in-net.aspx


If the interviewer asks to implement Observer design pattern without using Observer classes and interfaces, you can use the following simple example!

MyObserver as observer interface

interface MyObserver {

    void update(MyObservable o, Object arg);
}

MyObservable as Observable class

class MyObservable
{
    ArrayList<MyObserver> myObserverList = new ArrayList<MyObserver>();

    boolean changeFlag = false;

    public void notifyObservers(Object o)
    {
        if (hasChanged())
        {
            for(MyObserver mo : myObserverList) {
                mo.update(this, o);
            }
            clearChanged();
        }
    }


    public void addObserver(MyObserver o) {
        myObserverList.add(o);        
    }

    public void setChanged() {
        changeFlag = true;
    }

    public boolean hasChanged() {
        return changeFlag;
    }

    protected void clearChanged() {
        changeFlag = false;
    }

    // ...
}

Your example with MyObserver and MyObservable!

class MessageBoard extends MyObservable {
  private String message;

  public String getMessage() {
    return message;
  }

  public void changeMessage(String message) {
    this.message = message;
    setChanged();
    notifyObservers(message);
  }

  public static void main(String[] args) {
    MessageBoard board = new MessageBoard();
    Student bob = new Student();
    Student joe = new Student();
    board.addObserver(bob);
    board.addObserver(joe);
    board.changeMessage("More Homework!");
  }
}

class Student implements MyObserver {

  @Override
  public void update(MyObservable o, Object arg) {
    System.out.println("Message board changed: " + arg);
  }

}

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


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().


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.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to design-patterns

How to implement a simple scenario the OO way Implementing Singleton with an Enum (in Java) What is difference between MVC, MVP & MVVM design pattern in terms of coding c# Best Practices for mapping one object to another REST API Login Pattern When should we use Observer and Observable? How to implement a FSM - Finite State Machine in Java Function in JavaScript that can be called only once Thread Safe C# Singleton Pattern Repository Pattern Step by Step Explanation

Examples related to observable

Http post and get request in angular 6 Angular 4: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable How can I create an observable with a delay Return an empty Observable Angular/RxJs When should I unsubscribe from `Subscription` Using an array from Observable Object with ngFor and Async Pipe Angular 2 How to get data from observable in angular2 How to catch exception correctly from http.request()? How to create an Observable from static data similar to http one in Angular?

Examples related to observer-pattern

Delegation: EventEmitter or Observable in Angular When should we use Observer and Observable? Determine what attributes were changed in Rails after_save callback? Super-simple example of C# observer/observable with delegates

Examples related to observers

When should we use Observer and Observable?