____ /\ /\ 今日はおいらがオブザーバパターンを /( ●) (●)\ 解説するお!! / :::::⌒(__人__)⌒:::::\ | |r┬-| | \ ` ー'´ / ____ /⌒ ⌒\ まず、ヲチ(監視)したい対象を決めるお。 /( ―) (―)\ ヲチしたいと思った人がオブザーバだお /::::::⌒(__人__)⌒::::: \ | | \ / ____ /_ノ ヽ_\ ヲチされるほうは、パブリッシャとかって /( ●) ( ●)\ 呼ばれるお。新聞とかブログとかで例えると / ::::::⌒(__人__)⌒:::::\ わっかりやすいお。ヲチするほうは、 |  ̄ | 購読者だからサブスクライバだお \ / カタカナが難しいなら出版社と購読者だお ____ / ⌒ ⌒ \ おいらはおいらが好きだから ./( ―) ( ●) \ やる夫で学ぶデザインパターンを購読するお。 /::⌒(_人_)⌒::::: | フィードビューアにRSSフィードを登録して | ー .| おいらはオブザーバになったお。 \ / ____ /⌒ ⌒\ フィードを登録しておくと、 /( >) (<)\ やる夫で学ぶデザインパターンが更新されると /::::::⌒(__人__)⌒::::: \ 新しい記事が見れるようになるお!! | /| | | | | | \ (、`ー―'´, /  ̄ ̄ ̄ ____ / \ このふわっとした要約を / ─ ─\ NicoshBrothersXの実装で / (●) (●) \デザインパターンの解説してみるお | (__人__) | / ∩ノ ⊃ / ( \ / _ノ | | .\ “ /__| | \ /___ / public interface Observer { // 通知を受ける public void update( int hp, int sp, string itemNm ); } / ̄ ̄ ̄\ オブザーバのインターフェイスだお。 / \ 体力とか必殺ゲージとか保持アイテムが / ─ ─ ヽ 変わったらupdateを呼んでほしいお | (●) (●) | \ (__人__) __,/ / \ public interface Subject { // オブザーバを登録できる。 public void registerObserver( Observer obsrvInst ); // 登録したオブザーバを削除できる。 public void removeObserver( Observer obsrvInst ); // 登録したオブザーバに通知する。 public void notifyObservers(); } / ̄ ̄ ̄\ こっちはさっきの説明で言う / \ 出版社だお。 / ⌒ ⌒ \. notifyObserversがオブザーバの | (●)::::::(●) | updateを使うメソッドだお。 \ :::: (__人__) :::: / /. . `V´ \ ____ /\ /\ じゃあインプリメントしてみるお /( ●) (●)\ / :::::⌒(__人__)⌒:::::\ | |r┬-| | \ ` ー'´ / public class NicoshData implements Subject { private ArrayList observers; private int hitPoint; private int nicoshPoint; private String currentItem; public NicoshData(){ observers = new ArrayList(); } // オブザーバを登録していく public void registerObserver( Observer obsrvInst ){ observers.add( obsrvInst ); } // 通知の必要がなくなったら削除していく public void removeObserver( Observer obsrvInst ){ int idx = observers.indexOf( obsrvInst ); if( idx >= 0 ){ observers.remove( idx ); } } // リスト内のオブザーバに通知していく public void notifyObservers(){ for( int idx = 0; idx < observers.size(); idx++ ){ Observer observer = ( Observer )observers.get( idx ); observer.update( hitPoint, nicoshPoint, currentItem ); } } // hitPoint / nicoshPoint / currentItem のプロパティセッター } ____ /_ノ ヽ_\ Subjectのインプリメントは /( ●) ( ●)\ こんな感じだお / ::::::⌒(__人__)⌒:::::\ 続いてObserverだお |  ̄ | \ / // 文字表示をするクラス public class CharactericDsp implements Observer { private Subject nicoshData; private int hitPoint; private int nicoshPoint; private String currentItem; // コンストラクタでSubjectの参照をもらって登録する public CharactericDsp( Subject nicoshData ){ this.nicoshData = nicoshData; nicoshData.registerObserver( this ); } public void update( int hp, int sp, string itemNm ){ this.hitPoint = hp; this.nicoshPoint = sp; this.currentItem = itemNm; // 通知を受けたら文字表示処理を行う。 System.out.println( "HP:" + hitPoint + " SP:" + nicoshPoint + " アイテム:" + currentItem ); } // Subjectの参照を持っていると自身で監視の削除が出来る public unSubscribe(){ this.nicoshData.removeObserver( this ); } } // グラフ表示をするクラス public class GraphDsp implements Observer { // } // イメージで表示するクラス「><大変!」とか。 public class ImageDsp implements Observer { // } ____ /⌒ ⌒\ これでオブザーバインターフェイスを /( ―) (―)\ インプリメントしていればどんなクラスでも /::::::⌒(__人__)⌒::::: \ NicoshDataの内容通知が受けられるお | | updateの内容は実装依存だお \ / クラスごとに好き勝手に振舞いを決めればいいお ____ /_ノ ヽ_\ さらに調子に乗って /( >) (<)\ java.uril.Observerの解説もするお! /::::::⌒(__人__)⌒::::: \ | |r┬-/ | \ ` ̄'´ / import java.uril.Observable; // Subject import java.util.Observer; public class CharactericDsp implements Observer { private Observable observable; private int hitPoint; private int nicoshPoint; private String currentItem; // コンストラクタでSubjectの参照をもらって登録する public CharactericDsp( Observable observable ){ this.observable = observable; // nicoshData.registerObserver( this ); observable.addObserver( this ); } public void update( Observable obs, Object arg ){ if( obs instanceof NicoshData ){ NicoshData nicoshData = ( NicoshData )obs; this.hitPoint = nicoshData.getHitPoint(); this.nicoshPoint = nicoshData.getNicoshPoint(); this.currentItem = nicoshData.getCurrentItem(); // 通知を受けたら文字表示処理を行う。 System.out.println( "HP:" + hitPoint + " SP:" + nicoshPoint + " アイテム:" + currentItem ); } } // Subjectの参照を持っていると自身で監視の削除が出来る public unSubscribe(){ // this.nicoshData.removeObserver( this ); this.nicoshData.deleteObserver( this ); } } ____ / ⌒ ⌒ \ updateの引数をみると ./( ―) ( ●) \ Observableが渡ってくるお。 /::⌒(_人_)⌒::::: | データをプル(とる)しているんだお。 | ー .| \ / Observableは以下のメソッドが用意されてるお void addObserver(Observer o) protected void clearChanged() int countObservers() void deleteObserver(Observer o) void deleteObservers() boolean hasChanged() void notifyObservers() void notifyObservers(Object arg) protected void setChanged() γ⌒) )) オブザーバをまとめるお! / ⊃__ オブザーバパターンを使うと。。 〃/ / ⌒ ⌒\ γ⌒)( ⌒) (⌒) \ ∩⌒) / _ノ :::⌒(__人__)⌒ 〃/ ノ ( <| | |r┬( / / )) ( \ ヽ \ _`ー‐' /( ⌒) / / / ̄ ̄\ 相互にやり取りするオブジェクト間を / _ノ \ ___(⌒ヽ | ( ●)(●) /⌒ ⌒⊂_ ヽ . | (__人__) (⌒ヽ∩/( ⌒) (⌒) |(⌒ヽ | ` ⌒´ノ ヽ ノ| :::⌒(__人__)⌒ ::| ⊂ `、 . | } \ \ )┬-| / /> ) )) . ヽ } .(( (⌒ )、 ヽ_ `ー‐' ,// / ヽ ノ \ \ / / / く ヽ_ ノ ( 相互にやり取り・・・ 疎結合に設計できるようになるお!!! __ γ⌒) )) γ⌒) ))\ / ⊃__ / ⊃ _ノ \ ∩⌒) )) 〃/ / ⌒ ⌒\ 〃/ / ( ●)(●) / ノ γ⌒)( ⌒) (⌒) \ ∩⌒) γ⌒) (__人__)/ / )) / _ノ :::⌒(__人__)⌒ 〃/ ノ / _ノ .` ⌒´ノ( ⌒) ( <| | |r┬( / / )) ( < }/ /. ( \ ヽ \ _`ー‐' /( ⌒) (( \ ヽ . } / / / こうか? / ̄ ̄\ / _ノ \ やる夫。今回はちゃんとまとまったな。 | ( ●)(●)l お前に任しておけばプロジェクトは . | (__人__) | 安泰だ。会社も安泰だ。 | ` ⌒´ | いや、俺を弟子にしてほしいくらいだ。 . | } . ヽ } ヽ ノ / く / ヽ __ .-´ ``ヽ / ⌒ `ヽ 今までのことは水に流すお。 / `ヽ ヽ おいらについてこいだお。 (( / (●) ヽ |::⌒(__ (● ) | ヽ 人__) ⌒:::: | ヽ(__ン | 人 / | | / _ノ ノノ | `――――――――――――○―――――――――――――――’ O ガバッ ! ! ______ o /:υ::─ニjjニ─ヾ /:::li|.:( ○)三 ( ○)\ (:::||!.:υ::::: (__人__)):::: i| 〃 ):::::::::::. |r┬-| li::::/ ____ /: : : : : : l\`ー '/j: : ::ヽ ||13: 00 || | \ヽ :ヽ: : : : 7ヽ />: : : :r:\  ̄ ̄ ̄ ̄ ( ̄ ⌒⌒⌒⌒ ̄⌒ ⌒ ⌒ヽ ヽ ,.-―- 、 \ ヽ /::::::::::::::::::ヽ \ ____ / \ え。。。もう会社来なくていいのかお。。。? /:::::::::::::::: \ _ /:::::::::::::::: || | |:::::::::::::::::::::::: ∩! ,ヽ _ \:::::::::::::::: | ー ノ | ::::::::::::::: | i j  ̄ ̄ ̄| | ::::::::::::: ゝ__/____i | :::::::::: / / (__(__ ヽ⌒⌒⌒ヽ / ,_/ ___ノ / `ー' `ー' /
Observerパターンはオブジェクト間の1対多の依存関係を定義し、あるオブジェクトの状態が変化すると、それに依存している全てのオブジェクトが自動的に通知され更新されるようにします。
前回はシモネタで今回は夢オチというひどい有様で小学生並みの着地点です。もうほんとびっくりです(今日の晩飯が出前のピザだったことが)










