Version 0.1
Copyright © 2007 Lars Vogel
01.07.2009
| Revision History | ||
|---|---|---|
| Revision 0.1 | 01.07.2009 | Lars Vogel |
| Separated from http://www.vogella.de/articles/DesignPatterns/article.html | ||
Table of Contents
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.
The objects which are watching the state changes are called observer. Alternatively observer are also called listener.
The object which is being watched is called subject.
View A is the subject. View A displays the temperature of a container.
View B display a green light is the temperature is above 20 degree Celsius. Therefore View B registers itself as a Listener to View A.
If the temperature of View A is changed an event is triggered. That is event is send to all registered listeners in this example View B. View B receives the changed data and can adjust his display.
In the following example the observer is watching changes in the element of a pre-defined list of people.
package mydomain; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class MyModel { private List<Person> persons = new ArrayList<Person>(); private List<PropertyChangeListener> listener = new ArrayList<PropertyChangeListener>(); public class Person { private String firstName; private String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; notifyListeners(); } } public List<Person> getPersons() { return persons; } public MyModel() { // Just for testing we hard-code the persons here: persons.add(new Person("Lars", "Vogel")); persons.add(new Person("Jim", "Knopf")); } private void notifyListeners() { for (Iterator iterator = listener.iterator(); iterator.hasNext();) { PropertyChangeListener name = (PropertyChangeListener) iterator .next(); name.propertyChange(null); } } public void addChangeListener(PropertyChangeListener newListener) { listener.add(newListener); } }
package myobserver; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import mydomain.MyModel; public class MyObserver implements PropertyChangeListener { public MyObserver(MyModel model) { model.addChangeListener(this); } @Override public void propertyChange(PropertyChangeEvent arg0) { System.out.println("Things are changing..."); } }
package main; import java.util.Iterator; import mydomain.MyModel; import mydomain.MyModel.Person; import myobserver.MyObserver; public class Main {/** * @param args */public static void main(String[] args) { MyModel model = new MyModel(); MyObserver observer = new MyObserver(model); // We change the last name of the person, observer will get notified for (Iterator iterator = model.getPersons().iterator(); iterator .hasNext();) { Person person = (Person) iterator.next(); person.setLastName(person.getLastName() + "new"); } // We change the first name of the person, observer will get notified for (Iterator iterator = model.getPersons().iterator(); iterator .hasNext();) { Person person = (Person) iterator.next(); person.setFirstName(person.getFirstName() + "new"); } } }
The observer pattern allow for Open Closed Principle. The subject can registered an unlimited number of observers. If a new listener should register at the subject no code change in the subject is necessary.
The subject and the observer are loosely coupled. If a controller is used then neither the subject nor the observer have direct knowledge about each other. If no controller is used then only the observer has a knowledge about the subject.
Before posting questions, please see the vogella FAQ. If you have questions or find an error in this article please use the www.vogella.de Google Group. I have created a short list how to create good questions which might also help you.