観察者設計モードVsイベント依頼(java)


観察者設計モードVsイベント依頼
デザインモードJavaイベントの依頼
転載は元のブログの住所を明記してください.http://blog.csdn.net/gdutxiaoxu/article/details/51824769
ソースのダウンロード先:http://download.csdn.net/detail/gdutxiaoxu/9567209
このブログでは主にいくつかの問題を説明します.
  • 観察者モードとは?
  • 観察者モードの長所と短所
  • 観察者モードの欠点をどう思いますか?
  • 事件の依頼
  • 観察者モードとは?
    簡単に言えば、複数の観察者が同じテーマのオブジェクトを同時に観察したい場合、テーマのオブジェクトの状態が変化すると、観察者は自分自身の方法を見直して自分を更新することができます.
    観察者モードのクラスUML図
    观察者设计模式 Vs 事件委托(java)_第1张图片
    ステップを実行
  • は、観察者インターフェース
  • を定義する.
  • 観察者実装観察者インターフェース
  • 通知者インターフェースがあります.中にはaddObserver、removeObserver、notifyObserverがあります.
  • 観察者が変化したときに、notifyObservers()を呼び出し、Listを巡回して、observer内の方法を調べる
  • .
    例:
  • Androidシステムのコンテンツ提供者は、このような観察者モード
  • を採用している.
  • RecyCleerViewとListViewのAdapterは観察者モードを採用しています.RecyclerViewのAdapterはどのように観察者モードを実現していますか?私のこのブログを参照してください.
  • は、2つのインターフェースがダウンロードの進行度を同時に観察したい場合、観察者モードを採用してデビレーションすることができる.
  • 情景の実例
    クラス担任が来ましたAさんはBさんに言いました.「今日は本当に笑いました.私たちのクラスのクラスメートが注意深い時にNBAの試合を見ていて、担任に捕まってしまいました.担任の顔が青くなりました.ははははははは、本当に笑いました.」Bさんは言いました.えっと、どうやって授業でテレビを見られますか?Aさんは「ないです.彼らの男性たちはよく自習する時に試合を見ます.私たちのクラスの女子学生が前列に座っています.その男子学生たちは彼女にプレゼントを書いたりします.クラスの先生が来ました.その女の子はテーブルをノックするように言いました.Bさんはいいですよね.これでいいです.今日はどうして誰かが捕まるのですか?「Aさんが言いました.」これはちょうど担任が来た時、その女の子がトイレに行きました.その結果、漫画を読んでいた男性は捕まられず、NBAの試合を見ていた男性が捕まりました.携帯は全部没収されました.」Bさんは言いました.「はい.このシーンは、観察者モードというデザインを思い出させてくれました.教えてあげましょうか?」Aさんは血を吐いて、倒れてしまいました..
    コードの例:
  • まず、観察者インターフェース
  • を見てみましょう.
    
    public interface Subject {
    
        /** *       * @param observer */
        void addObserver(Observer observer);
        /** *          * @param observer */
        void removeObserver(Observer observer);
        /** *          */
        void removeAll();
    
        /** * data             *   Object       ,      ,             * @param data */
        void notifyAllObserver(Object data);
    
        /** *             * @param observer * @param data * data             *   Object       ,      ,             */
        void notify(Observer observer,Object data);
    
    }
  • 続いて、まず観察者インターフェース
  • を見に行きます.
    /** *       * @author Administrator * */
    public interface Observer {
    
        /** * * @param subject      * @param data                */
        void update(Subject subject,Object data);
    
    
    }
  • 次はCocrete Subjectがどのように実現されているかを見てみます.
  • は、単に観察者を追加すると、現在の観察者が存在するかどうかを判断し、存在しないと、Listセットに追加する
  • である.
  • 観察者を削除すると、Listセットから直接に
  • を除去する.
  • Subjectの状態が変化すると、Listを巡回し、Observerのudate方法を呼び出して自身を更新する
  • .
    /** *         *               , *          java.util   Observable * @author xujun * */
    
    public class ConcreteSubject implements Subject {
    
        List<Observer> mList = new ArrayList<>();
    
        @Override
        public void addObserver(Observer observer) {
            //              
            if (observer == null) {
                throw new NullPointerException("observer == null");
            }
    
            if (!mList.contains(observer)) {
                mList.add(observer);
            }
    
    
        }
    
        @Override
        public void removeObserver(Observer observer) {
            mList.remove(observer);
    
        }
    
        @Override
        public void removeAll() {
           mList.clear();
        }
    
    
    
        @Override
        public void notifyAllObserver(Object data) {
            for (Observer observer : mList) {
                observer.update(this,data);
            }
    
        }
    
        @Override
        public void notify(Observer observer, Object data) {
            if(observer!=null){
                observer.update(this, data);
            }
    
        }
    
    }
  • 最後に具体的なCocrete Observerは具体的に何をしましたか?ここでは便利にするために、現在のクラス名と通知者からのメッセージを印刷するだけです.具体的な状況の中で、Object dataを持って自分の状態を更新することができます.
  • public class NBAObserver implements Observer {
    
        @Override
        public void update(Subject subject, Object data) {
            System.out.println( "   "+this.getClass().
                    getSimpleName()+", "+data+"  NBA ");
    
        }
    
    }
    
    public class ConcreteObserver2 implements Observer public class CartoonObserver implements Observer {
    
        @Override
        public void update(Subject subject, Object data) {
            System.out.println( "   "+this.getClass().
                    getSimpleName()+", "+data+"     ");    
        }
    
    }
  • テストコードを実行してください.
    public class TestObserver {
    
        public static void main(String[] args) {
            ConcreteSubject concreteSubject = new ConcreteSubject();
            CartoonObserver cartoonObserver = new CartoonObserver();
            NBAObserver nbaObserver = new NBAObserver();
            concreteSubject.addObserver(cartoonObserver);
            concreteSubject.addObserver(nbaObserver);
    
            concreteSubject.notifyAllObserver("    ");
    
        }
    
    }
    私たちは以下の情報を出力するのを見ることができます.
    カートゥーンObserverです.先生が来たら漫画を見ないでください.
    私はNBB Observerです.先生が来たらNBAを見ないでください.
    観察者モードの実現分析はここまでです.
    観察者モードの長所と短所
    長所
    よく通知者と観察者を結合しました.観察者は通知者の内部がどのように実現されているかを知る必要がなく、後日コードの修正に便利で、逆転に依存する原則を体現しています.
    短所分析:
    分析:
  • 「上のこのマシンのコードの中の抽象的な通知者はやはり抽象的な観察者に依存しています.もし抽象的な観測者がいなかったら、機能が完成しないのではないですか?
  • また、あなたがこのコードで書いたので、対象の更新の動きは同じです.もし私の対象が更新されたらどうなりますか?例えば、NBAの試合を見ていたら、担任が来たらトイレに行きます.漫画を見ていたら、担任が来たら本を読み続けます.コードはどう書きますか?
  • Bさんは「行ってきます.あなたが寝ていると思っていました.聞いていましたか?とても嬉しいです.次は「事件依頼」というものを使ってこの問題を解決します.
  • Aさんは「私の神は、事件の依頼とは何ですか?」
    解決方法
    1.解決方法、利用イベント依頼
    イベント依頼
    まず、私たちの通知者GoodNotifierはどうやって実現されたのかを見てみましょう.
    public class GoodNotifier extends Notifier {   
    
        @Override  
        public void addListener(Object object, String methodName, Object... args) {   
            System.out.println("               !");   
            EventHandler handler = this.getEventHandler();
            handler.addEvent(object, methodName, args);   
        }   
    
        @Override  
        public void notifyX() {   
            System.out.println("                   :    ");   
            try{   
                this.getEventHandler().notifyX();   
            }catch(Exception e){   
                e.printStackTrace();   
            }   
        }   
    
    }   
    次に私達はその父の種類のNotifierがどのように実現したのかを見に来ました.
    /** *          * @author xujun * */
    public abstract class Notifier {
        private EventHandler eventHandler = new EventHandler();
    
        public EventHandler getEventHandler() {
            return eventHandler;
        }
    
        public void setEventHandler(EventHandler eventHandler) {
            this.eventHandler = eventHandler;
        }
    
        /** *                * * @param object          * @param methodName           * @param args         */
        public abstract void addListener(Object object, String methodName,
                Object... args);
    
        /** *             :     */
        public abstract void notifyX();
    }
    上のnotifierのコードを見たら、あなたはどこかで会ったような感じがしますか?私たちの観察者モードの通知者と似ていると感じますか?
  • 観察者モードの私達の通知者はこのように実現された
  • です.
    @Override
        public void notifyAllObserver(Object data) {
            for (Observer observer : mList) {
                observer.update(this,data);
            }
    
        }
  • 事件の依頼の中で私達はこのように実現しました.
     @Override  
        public void notifyX() {   
            System.out.println("                   :    ");   
            try{   
                EventHandler handler = this.getEventHandler();
                handler.notifyX();   
            }catch(Exception e){   
                e.printStackTrace();   
            }   
        }   
  • の違いは、実際にはEventHandlerに渡しても、
  • を処理します.
    Event Handlerを見てみましょう.私たちはどうやって実現しましたか?
    /** *         * @author Administrator * */
    public class EventHandler {   
        //    List 
        private List<Event> objects;   
    
        public EventHandler(){   
            objects=new ArrayList<Event>();   
        }   
        //            ,       
        public void addEvent(Object object,String methodName,Object...args){   
            objects.add(new Event(object,methodName,args));   
        }   
        //               
        public void notifyX() throws Exception{   
            for(Event e : objects){   
                e.invoke();   
            }   
        }   
    } 
    実は観察者モードと同じで、私達は私達の事件の対象を保存します.
    objects=new ArrayList<Event>();  
    
    イベントを追加するとイベントをEventオブジェクトとしてパッケージ化して、objectに追加します.
    objects.add(new Event(object,methodName,args));   
    
    私たちはイベントをお知らせする時、またListを巡回して、各イベントの対象をお知らせします.
    for(Event e : objects){   
         e.invoke();   
    } 
    invoke()という方法を見て、何かを思いつきましたか?間違いなく、javaの反射メカニズムです.私達はEventクラスに入れました.Event類はどのように実現されたのかを見てみます.
    この記事を参照してください.http://blog.csdn.net/XIAXIA__/articale/detail/41803473
    http://blog.csdn.net/yanshujun/article/details/6494447
    コードの中で、私達は抽象的な観察者という類を取り除いて、クライアントによって決定してどの観察者に通知する必要がありますか?PS:Javaにはcxi delegateのようなものがないので、Javaの中の反射で実現します.下記のコードをご覧ください.
    /** *          * @author Administrator * */
    public class Event {   
        //         
        private Object object;   
        //         
        private String methodName;   
        //         
        private Object[] params;   
        //           
        private Class[] paramTypes;   
    
        public Event(){   
    
        }   
    
        public Event(Object object,String methodName,Object...args){   
            this.object=object;   
            this.methodName=methodName;   
            this.params=args;   
            contractParamTypes(this.params);   
        }   
        //               
        private void contractParamTypes(Object[] params){   
            this.paramTypes=new Class[params.length];   
            for(int i=0;i<params.length;i++){   
                this.paramTypes[i]=params[i].getClass();   
            }   
        }   
    
    
        public Object getObject() {
            return object;
        }
    
      //       get set  
    
        /** *          ,    ,      ,      * @throws Exception */
        public void invoke() throws Exception{   
            Method method=object.getClass().getMethod(this.getMethodName(), this.getParamTypes());   
            if(null==method){   
                return;   
            }   
            method.invoke(this.getObject(), this.getParams());   
        }   
    }
    Eventクラスで私たちinvoke()の方法でやっている仕事は、私たちのオブジェクトのメソッド名、メソッドパラメータに基づいて、送信による方法です.
    テストコードを実行してください.
            //             
            Notifier goodNotifier=new GoodNotifier();   
    
            //          ,      
            WatchCartoonListener playingGameListener=new WatchCartoonListener();   
            //          ,      
            WatchingNBAListener watchingTVListener=new WatchingNBAListener();   
            //             ,         
            goodNotifier.addListener(playingGameListener, "stopPlayingGame",new Date());   
            //             ,         
            goodNotifier.addListener(watchingTVListener, "stopWatchingTV",new Date());   
            try{   
                //      
                Thread.sleep(1000);   
            }catch(Exception e){   
                e.printStackTrace();   
            }   
            //    ,              :     
            goodNotifier.notifyX();
    
    結果は以下のとおりです
    Watch CatoonListener漫画を読んでいます.開始時間:Mon Jul 04:13:25 CST 2016
    Watch ingNBBAListenserはNBAを見ています.開始時間はMon Jul 04:13:25 CST 2016です.
    新しいクラスメイトに頼まれて責任を果たす見張り人がいます.
    新しいクラスメイトに頼まれて責任を果たす見張り人がいます.
    職責を全うする見張り人は、すべての手伝いが必要な学生に教えました.先生が来ました.
    Watch CatoonListener先生が来ました.漫画を見ないでください.終了時間:Mon Jul 04:25:34 CST 2016
    Watch ingNBBAListens先生が来ました.NBAの生放送を早く閉じてください.終了時間はMon Jul 04:25:34 CST 2016です.
    締め括りをつける
    観察者の長所と短所
    利点はコードをよく結合し、逆転に依存する原則を体現している.
    短所:
  • 抽象的な通知者はやはり抽象的な観察者に頼っています.観察者がいないと更新できません.
  • は、観察者のすべての動作が同じでなければならないと要求しています.もし違ったら、
  • は実現できません.
    イベント依頼メカニズム分析
  • 見張り人は全く遊び人の存在を知らず、完全にデカップしています.(もちろん、功労はEventとEvent Handlerのおかげです.そして、この二つの種類は共通性があります.)
  • 先生が来たらゲームをやめて席に戻ります.NBAを見る人はNBAを見るのをやめて、漫画を読むのをやめて、ゲームをします.(一回の通知で、同じではない方法を実行した)
  • 拡張性が高くて、もう一人のバスケットボールをする学生は先にバスケットボールの学生類を書いて、テストコードの中で守備者に教えてくれればいいです.見張り人は全然変わりません.重用性が良いです.
    PS:このブログを書くためにも、かなり疲れました.前と後でいろんな資料を調べましたが、価値があります.観察者モードに対する理解を深めました.もっと重要なのは、実際に反射機構を使う方法を習得しました.
    参考記事:http://blog.csdn.net/XIAXIA__/articale/detail/41803473
    転載は元のブログの住所を明記してください.http://blog.csdn.net/gdutxiaoxu/article/details/51824769
    ソースのダウンロード先:http://download.csdn.net/detail/gdutxiaoxu/9567209