Design Pattern Series - Part Four: Observer pattern

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;
    }


}

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;
    }


}

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());

    }

}

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);
}

Observer interface:

package custom_observerpattern;

/**
 *
 * @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;
    }

}

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;
    }

}

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());

    }
}

One response on “Design Pattern Series – Part Four: Observer pattern

  1. streetspirit December 18, 2012 at 11:25 pm

    Well done, keep it coming 🙂

Leave a Reply