Observer pattern

Observer pattern

software_development

The observer pattern is used when an object has to notify a change of state to other objects, which are updated automatically.

A practical example

Suppose we have a class StatusChecker that notifies a change of status to two Monitors.


class StatusChecker {
	MonitorTypeA monitorTypeA;
	MonitorTypeB monitorTypeB;

	public void onChangeStatus() {
		monitorTypeA.statusChanged();
		monitorTypeB.statusChanged();
	}

	public Status getStatus(){
		return this.status;
	}
}

class MonitorTypeA {
	public function statusChanged() {
		Status status = this.monitor.getStatus();
		[...]
	}
}

class MonitorTypeB {
	public function statusChanged() {
		Status status = this.monitor.getStatus();
		[...]
	}
}	

As we can see, the StatusChecker calls the statusChanged method of each monitor, then the monitors get the status by calling the getStatus method of the StatusChecker. This means that there is a bidirectional relationship between each monitor and the checker class.

There are many flaws in this structure:

  • What if we want to add a new Monitor type to the StatusChecker? We would have to add a new field and add a new statusChanged line on the onChangeStatusMethod.
  • What if we want to compile the each class in a different package?

All of these problems can be solved by making this relationship unidirectional. Let’s see how:


class StatusChecker {
	List<Observer> observers;

	public void addObserver(Observer observer) {
		observers.push(observer);
		}

	public void onChangeStatus() {
		for (Observer observer : observers) {
			observer.statusChanged(this.Status);
		}
	}
}

public interface Observer{
	public function statusChanged(Status status);
}

class MonitorTypeA implements Observer {
	public function statusChanged(Status status) {
		[...]
	}
}

class MonitorTypeB implements Observer {
	public function statusChanged(Status status) {
		[...]
	}
}

Now StatusChecker is not aware of the monitors existence and any object that implements the Observer interface can add himself to the observers of the StatusChecker status. Because there is no direct dependency, we can compile these 3 classes indipendently.

Related News