デザインパターンを覚えたい (Observer)

Observerパターン

状態変化を他のオブジェクトに通知するパターン。
ポイントは

  • 通知によって複数オブジェクト間で同期を取れる

ことかな。前回のMediatorパターンと似てるけど、こっちは通知することが主目的。

実装。いい例が思い浮かばなかったので今回は非常に単純なのですいません。
http://dl.dropbox.com/u/7810000/code/design_pattern/observer.zip

実行。

$ ant test
Buildfile: /Users/xxx/tmp/observer/build.xml

build:

test:
[java] exception : java.lang.ArithmeticException: / by zero
[java] 1: ...
[java] 2: ...
[java] 3: ...
[java] exception : java.lang.ArrayIndexOutOfBoundsException: 5
[java] 1: ...
[java] 2: ...
[java] 3: ...
[java] exception : java.lang.NullPointerException
[java] 1: ガッ
[java] 2: ガッ
[java] 3: ガッ

BUILD SUCCESSFUL
Total time: 2 seconds

ポイントは以下のようにSubjectにObserverを登録して、Subject内でObserverのメソッドを叩いているところ。

public class Main {
    public static void main(String[] args) {
        Subject subject = new ExceptionSubject();

        subject.addObserver(new ExceptionObserver());
        subject.addObserver(new ExceptionObserver());
        subject.addObserver(new ExceptionObserver());

        subject.execute();
    }
}
public class ExceptionSubject extends Subject {
    public ExceptionSubject() {
        super();
    }

    public void execute() {
        try {
            int a = 0;
            int b = 2;
            int c = b / a;
        } catch (Exception e) {
            System.out.println("exception : " + e);
            notifyObservers(e);
        }

        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            System.out.println("exception : " + e);
            notifyObservers(e);
        }

        try {
            int[] array = new int[5];
            for (int i=0; i<=5; i++) {
                array[i] = i;
            }
        } catch (Exception e) {
            System.out.println("exception : " + e);
            notifyObservers(e);
        }

        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            System.out.println("exception : " + e);
            notifyObservers(e);
        }

        try {
            String nullStr = null;
            int nullLength = nullStr.length();
        } catch (Exception e) {
            System.out.println("exception : " + e);
            notifyObservers(e);
        }
    }
}

ちなみにObserver側の実装はこんな感じ。

public class ExceptionObserver implements Observer {

    /* 中略 */

    public void update(Object event) {
        if (event instanceof NullPointerException) {
            System.out.println(Integer.toString(observeId) + ": ガッ");
        } else {
            System.out.println(Integer.toString(observeId) + ": ...");
        }
    }
}