Design Pattern Series – Part Four: Observer pattern
Today I’m adding another important design pattern to the toolbox. Observer Pattern is commonly used and quite powerful.
The Observer Pattern defines one to many dependency between objects so that when one object changes state, all of it dependents are notified and updated.
We can create a class structure for the pattern ourselves from scratch or we can use build in Observer functionality in JDK.
Utilizing JDK Observer-Observable mechanism:
NameService.java
package jdk_observerpattern;
import java.util.Observable;
/**
*
* @author kris
*/
public class NameService extends Observable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.setChanged();
notifyObservers(name);
this.name = name;
}
}
import java.util.Observable;
/**
*
* @author kris
*/
public class NameService extends Observable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.setChanged();
notifyObservers(name);
this.name = name;
}
}
NameObserver.java
package jdk_observerpattern;
import java.util.Observable;
import java.util.Observer;
/**
*
* @author kris
*/
public class NameObserver implements Observer{
private final String objName;
public NameObserver(String observername){
this.objName = observername;
}
public void update(Observable o, Object o1) {
System.out.println("Observer: " + this.toString() + ", name changed: " + o1);
}
@Override
public String toString() {
return this.objName;
}
}
import java.util.Observable;
import java.util.Observer;
/**
*
* @author kris
*/
public class NameObserver implements Observer{
private final String objName;
public NameObserver(String observername){
this.objName = observername;
}
public void update(Observable o, Object o1) {
System.out.println("Observer: " + this.toString() + ", name changed: " + o1);
}
@Override
public String toString() {
return this.objName;
}
}
Main method for testing:
package jdk_observerpattern;
/**
*
* @author kris
*/
public class Main {
private NameService service;
private NameObserver observer1;
private NameObserver observer2;
public Main(){
service = new NameService();
observer1 = new NameObserver("First Observer");
observer2 = new NameObserver("Second Observer");
service.addObserver(observer1);
service.addObserver(observer2);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main m = new Main();
m.test();
}
public void test(){
System.out.println("Count: " + service.countObservers());
service.setName("Big Lebowsky");
System.out.println(service.getName());
}
}
/**
*
* @author kris
*/
public class Main {
private NameService service;
private NameObserver observer1;
private NameObserver observer2;
public Main(){
service = new NameService();
observer1 = new NameObserver("First Observer");
observer2 = new NameObserver("Second Observer");
service.addObserver(observer1);
service.addObserver(observer2);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main m = new Main();
m.test();
}
public void test(){
System.out.println("Count: " + service.countObservers());
service.setName("Big Lebowsky");
System.out.println(service.getName());
}
}
Custom Observer pattern implementation:
Subject interface
package custom_observerpattern;
/**
*
* @author kris
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers(Object obj);
}
/**
*
* @author kris
*/
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers(Object obj);
}
Observer interface:
package custom_observerpattern;
/**
*
* @author kris
*/
public interface Observer {
public void updateStatus(Object o);
}
/**
*
* @author kris
*/
public interface Observer {
public void updateStatus(Object o);
}
NameService:
package custom_observerpattern;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author kris
*/
public class NameService implements Subject {
private List<Observer> observers;
private String name;
public NameService(){
observers = new ArrayList<Observer>();
}
public void registerObserver(Observer o) {
this.observers.add(o);
}
public void removeObserver(Observer o) {
this.observers.remove(o);
}
public void notifyObservers(Object obj) {
for(Observer o : this.observers){
o.updateStatus(obj);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.notifyObservers(name);
this.name = name;
}
}
import java.util.ArrayList;
import java.util.List;
/**
*
* @author kris
*/
public class NameService implements Subject {
private List<Observer> observers;
private String name;
public NameService(){
observers = new ArrayList<Observer>();
}
public void registerObserver(Observer o) {
this.observers.add(o);
}
public void removeObserver(Observer o) {
this.observers.remove(o);
}
public void notifyObservers(Object obj) {
for(Observer o : this.observers){
o.updateStatus(obj);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.notifyObservers(name);
this.name = name;
}
}
NameObserver:
package custom_observerpattern;
/**
*
* @author kris
*/
public class NameObserver implements Observer {
private final String objName;
public NameObserver(String observername){
this.objName = observername;
}
public void updateStatus(Object o) {
System.out.println("Updating status: " + o);
}
@Override
public String toString() {
return this.objName;
}
}
/**
*
* @author kris
*/
public class NameObserver implements Observer {
private final String objName;
public NameObserver(String observername){
this.objName = observername;
}
public void updateStatus(Object o) {
System.out.println("Updating status: " + o);
}
@Override
public String toString() {
return this.objName;
}
}
Main class for testing purposes:
package custom_observerpattern;
/**
*
* @author kris
*/
public class Main2 {
private NameService service;
private NameObserver observer1;
private NameObserver observer2;
public Main2() {
service = new NameService();
observer1 = new NameObserver("First Observer");
observer2 = new NameObserver("Second Observer");
service.registerObserver(observer1);
service.registerObserver(observer2);
}
public static void main(String[] art) {
Main2 m = new Main2();
m.test();
}
public void test() {
service.setName("Big Lebowsky");
System.out.println(service.getName());
}
}
/**
*
* @author kris
*/
public class Main2 {
private NameService service;
private NameObserver observer1;
private NameObserver observer2;
public Main2() {
service = new NameService();
observer1 = new NameObserver("First Observer");
observer2 = new NameObserver("Second Observer");
service.registerObserver(observer1);
service.registerObserver(observer2);
}
public static void main(String[] art) {
Main2 m = new Main2();
m.test();
}
public void test() {
service.setName("Big Lebowsky");
System.out.println(service.getName());
}
}
Well done, keep it coming 🙂