Observer Design Pattern in Java

Observer design pattern

  1. Model the "independent" functionality with a "subject" abstraction
  2. Model the "dependent" functionality with "observer" hierarchy
  3. The Subject is coupled only to the Observer base class
  4. Observers register themselves with the Subject
  5. The Subject broadcasts events to all registered Observers
  6. Observers "pull" the information they need from the Subject
  7. Client configures the number and type of Observers
abstract class Observer {
    protected Subject subject;
    public abstract void update();
}

class Subject {
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public void add(Observer o) {
        observers.add(o);
    }

    public int getState() {
        return state;
    }

    public void setState(int value) {
        this.state = value;
        execute();
    }

    private void execute() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

class HexObserver extends Observer {
    public HexObserver(Subject subject) {
        this.subject = subject;
        this.subject.add(this);
    }

    public void update() {
        System.out.print(" " + Integer.toHexString(subject.getState()));
    }
}

class OctObserver extends Observer {
    public OctObserver(Subject subject) {
        this.subject = subject;
        this.subject.add( this );
    }

    public void update() {
        System.out.print(" " + Integer.toOctalString(subject.getState()));
    }
}

class BinObserver extends Observer {
    public BinObserver(Subject subject) {
        this.subject = subject;
        this.subject.add(this);
    }

    public void update() {
        System.out.print(" " + Integer.toBinaryString(subject.getState()));
    }
}

public class ObserverDemo {
    public static void main( String[] args ) {
        Subject sub = new Subject();
        // Client configures the number and type of Observers
        new HexObserver(sub);
        new OctObserver(sub);
        new BinObserver(sub);
        Scanner scan = new Scanner(System.in);
        for (int i = 0; i < 5; i++) {
            System.out.print("\nEnter a number: ");
            sub.setState(scan.nextInt());
        }
    }
}

Output

Enter a number: 55
 37 67 110111
Enter a number: 12
 c 14 1100
Enter a number: -10
 fffffff6 37777777766 11111111111111111111111111110110
Enter a number: 112
 70 160 1110000
Enter a number: 5
 5 5 101

Code examples