スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Javaライブラリから学ぶデザインパターン Observer

久々に『Javaライブラリから学ぶデザインパターン』のコーナーです。
今回はObserverパターンをご紹介します。
いつものようにパターンの具体的な適用例を見ていきましょう。

Observer パターンとは

Observer パターン - Wikipedia
Observer パターン(オブザーバ・パターン)とは、プログラム内のオブジェクトの状態を観察(observe)するようなプログラムで使われるデザインパターンの一種。出版-購読型モデルとも呼ばれる。暗黙的呼び出しの原則と関係が深い。

このパターンを使っているクラス

解説

Observerパターンには、SubjectとObserverという2つの要素が必ず登場します。
SubjectはObserverを持ち、自身の状態に変化があった場合、そのことをObserverに通知します。
同じことですが、ObserverはSubjectに保持され、Subjectからの通知を受け取ります。

さて具体例ですが、みなさんはAWTやSwingといったGUIツールキットを使ったことがありますか?
もし使ったことがあるなら間違いなくあなたはこのパターンを使っています。
何故ならUIコンポーネントがSubjectで、コンポーネントに仕込むリスナーがObserverだからです。
今回の例でいうと、AbstractButtonがSubjectで、ActionListenerがObserverになります。

ではコードを見てみましょう。
まずはActionListenerから。このクラスはコンポーネントに対し何らかのアクションが行われた際、
その通知を受け取るためのインタフェースです。
例えばボタンを表すJButtonやJToggleButtonなどに追加しておくと、
「ボタンが押されたよ」という通知を受け取ることができます。public interface ActionListener extends EventListener {

/**
* Invoked when an action occurs.
*/
public void actionPerformed(ActionEvent e);

}
非常に単純なインタフェースですね。

続いてAbstractButtonを見てみます。
このクラスはJButtonやJToggleButtonといったボタンの親クラスです。public abstract class AbstractButton extends
JComponent implements ItemSelectable, SwingConstants {

public void addActionListener(ActionListener l) {
listenerList.add(ActionListener.class, l);
}

public void removeActionListener(ActionListener l) {
if ((l != null) && (getAction() == l)) {
setAction(null);
} else {
listenerList.remove(ActionListener.class, l);
}
}

protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = getActionCommand();
}
e = new ActionEvent(AbstractButton.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}

}
addActionListenerメソッドでは、Observer(ActionListener)の追加を行っています。
そしてremoveActionListenerメソッドでは、Observerの削除を行っています。
肝心の通知の部分は、fireActionPerformedメソッドが担当しています。
このfireActionPerformedメソッドは、ボタンが押されたときにGUIツールキットから呼び出されます。
処理としては、ActionListenerが登録されていたらActionEventを生成し、
Observerへ通知する(ActionListenerのactionPerformedメソッドを呼び出す(36行目))ということをやっています。
ちなみにループの部分を見ればわかるように、リスナーの呼び出し順は登録した順序ではなく、
その逆順となっています。

まとめ

今回の例で見たように、Observerパターンは、状態が変わりうるオブジェクト(Subject)と、
状態が変更されたことを感知したいオブジェクト(Observer)の両方が存在する場合に適用することができます。
関連記事
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

Kenji Suzuki

Author:Kenji Suzuki
IT技術に関するあれこれを書いているブログです。
Pujohead Softの方では開発したソフトを公開しています。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
タグ

プログラミング デザインパターン コードリーディング bat 

検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
メールフォーム

名前:
メール:
件名:
本文:

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。