デザインパターンを覚えたい (Observer)
Observerパターン
状態変化を他のオブジェクトに通知するパターン。
ポイントは
- 通知によって複数オブジェクト間で同期を取れる
ことかな。前回のMediatorパターンと似てるけど、こっちは通知することが主目的。
実装。いい例が思い浮かばなかったので今回は非常に単純なのですいません。
http://dl.dropbox.com/u/7810000/code/design_pattern/observer.zip
実行。
$ ant test
Buildfile: /Users/xxx/tmp/observer/build.xmlbuild:
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) + ": ..."); } } }