Observer
Definition
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
UML class diagram
Participants
- Subject
- knows its observers. Any number of Observer objects may observe a subject
- provides an interface for attaching and detaching Observer objects.
- ConcreteSubject
- stores state of interest to ConcreteObserver
- sends a notification to its observers when its state changes
- Observer
- defines an updating interface for objects that should be notified of changes in a subject.
- ConcreteObserver
- maintains a reference to a ConcreteSubject object
- stores state that should stay consistent with the subject's
- implements the Observer updating interface to keep its state consistent with the subject's
Sample code in Java
package com.hong.observer; import java.util.LinkedList; import java.util.List; interface Observer { public void update(); } class ConcreteObserver implements Observer { private String name; private int state; private ConcreteSubject subject; public ConcreteObserver(ConcreteSubject subject, String name) { this.name = name; this.subject = subject; } @Override public void update() { this.state = subject.getSubjectState(); System.out.printf("%s state is %d ", this.name, this.state); } } class Subject { private List<Observer> observers = new LinkedList<Observer>(); public void Attach(Observer o){ observers.add(o); } public void Detach(Observer o){ observers.remove(o); } public void notifyObservers(){ for(Observer observer : observers){ observer.update(); } } } class ConcreteSubject extends Subject{ private int subjectState; public ConcreteSubject(){ subjectState = 0; } public int getSubjectState() { return subjectState; } public void setSubjectState(int subjectState) { this.subjectState = subjectState; } } public class Observer_structure { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); subject.Attach(new ConcreteObserver(subject, "observer1")); subject.Attach(new ConcreteObserver(subject, "observer2")); subject.Attach(new ConcreteObserver(subject, "observer3")); subject.notifyObservers(); subject.setSubjectState(3); subject.notifyObservers(); subject.setSubjectState(51); subject.notifyObservers(); } }