Observer pattern is behavioral pattern that 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.
Observer pattern uses three actor classes – Subject, Observer and Client. Subject is an object having methods to attach and detach observers to a client object. Observer is an abstract class, its implementations are attached to Subject while creation for further notification. See scheme below :
Step 1 : Create Subject class
public class Subject {
private List<Observer> observers = new ArrayList<>();
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 remove(Observer observer) {
observers.remove(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
Step 2 : Create Observer class
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
Step 3 : Create concrete observer classes
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()));
}
}
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() ) );
}
}
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 classes
public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();
Observer binaryObserver = new BinaryObserver(subject);
new OctalObserver(subject);
new HexaObserver(subject);
System.out.println("First state range: 15");
subject.setState(15);
subject.remove(binaryObserver);
System.out.println("Second state range: 10");
subject.setState(10);
}
}
The output will be :
First state change: 15 Binary String: 1111
Octal String: 17
Hex String: F Second state change: 10 Octal String: 12
Hex String: A