Javaデザインモード--オブザーバーモード

6312 ワード

学校にはとてもかわいい女の子がいて、多くの男の子が彼女のファンの仲間入りをして、みんなは先を争って彼女の情報を集めました.この时、女の子のルームメイト、同級生はすべて彼女に文句を言い始めて、彼女も罪悪感を感じて、周りの友达に迷惑をかけたと感じました.そこで、彼女は自分の状態を公開することにした.前提は彼女の周りの人に迷惑をかけないことだ.最初、彼女は自分の毎日の食事と勉强の状态を公开して、彼女のファンが彼女のここで登录する限り、苦労せずに自分の动态の情报を受け取ることができて、これはファンにとってまるで天の大きい良いニュースです...この时1人のプログラマーが通りかかって、この现象を见て、霊光がきらめいて、これは観察者のモードです.まず、女の子を1つのクラスに抽象化して、彼女の行為は私たちも方法を書くことができて、そこで次の2つのクラスがあります.
public interface Girl {
    public void addFans(Fans fans);

    public void removeFnas(Fans fans);

    public void notifyFans();
}

public class LovelyGirl implements Girl {
    private String eatState = "Inexact";
    private String studyState = "Inexact";
    private ArrayList fanses;

    public LovelyGirl() {
        fanses = new ArrayList<>();
    }

    @Override
    public void addFans(Fans fans) {
        fanses.add(fans);
    }

    @Override
    public void removeFnas(Fans fans) {
        int i = fanses.indexOf(fans);
        if (i >= 0) {
            fanses.remove(i);
        }
    }

    @Override
    public void notifyFans() {
        for (int i = 0; i < fanses.size(); i++) {
            Fans fans = fanses.get(i);
            fans.update(eatState, studyState);
        }
    }

    public void setEatState(String eatState) {
        this.eatState = eatState;
        notifyFans();
    }

    public void setStudyState(String studyState) {
        this.studyState = studyState;
        notifyFans();
    }
}

ここでは、女の子をインタフェースとして書きました.結局、人はいつも異思遷に会うのですか.もし学校にきれいな女の子が来たら?では、BeautyGirl種類が増えるかもしれません.女の子の話が終わったら、私たちもファンの話をしなければなりません.ファンはたくさんいます.彼らの目的も一つだけです.自分の好きな女の子の最新情報を取得します.じゃあ、女神と一致させるために、インタフェースも書いてあげましょう.
public interface Fans {
    public void update(String eatState, String studyState);
}

インタフェースがあれば、多くのファンがこのインタフェースを実現し、最新情報を得ることができます.例えばファンAとファンB-
public class FansOne implements Fans {

    @Override
    public void update(String eatState, String studyState) {
        System.out.println("I am fans one : " + eatState + ", " + studyState);
    }
}
public class FansTwo implements Fans {

    @Override
    public void update(String eatState, String studyState) {
        System.out.println("I am fans two : " + eatState + ", " + studyState);
    }
}

はい、すべての準備はもう終わりましたが、この時はもうお昼になりました.女の子は言いました.私は食事を始めます.例えば、下のように.
public class Client {
    public static void main(String[] args) {
        LovelyGirl girl = new LovelyGirl();

        FansOne fansOne = new FansOne();
        girl.addFans(fansOne);

        FansTwo fansTwo = new FansTwo();
        girl.addFans(fansTwo);

        girl.setEatState("I am eating");
    }
}

印刷結果は次のとおりです.
I am fans one : I am eating, Inexact
I am fans two : I am eating, Inexact

実は、上の例は私たちがよく言っている観察者パターンです.オブザーバモードは、オブジェクト間の一対のマルチ依存性を定義し、オブジェクトの状態が変化すると、すべての依存者が通知を受け取り、自動的に更新されます.天気予報購読システム、新聞購読システムなど、生活の中で多くの場所で使われています.
上の例では、プッシュ機能しか書いていないので、ファンが自分から情報を得ようとしたら?もしあるファンがあなたの学習状態に興味がなく、もう学習に関する情報を送りたくないと言ったら.では、どのように改善すればいいのでしょうか.ちょうどこの機会に、Javaが内蔵しているオブザーバーモードを見てみましょう.Javaは、ObserverインタフェースとObservableクラスを提供しています.次に、使用方法について説明します.
  • オブジェクトを観察者にするにはどうすればいいですか?観察者インタフェースが実装され、ObservableオブジェクトのaddObserver()メソッドが呼び出される.観察者オブジェクトになりたくない場合は、deleteObserver()メソッドを呼び出せばよい.
  • 観察者はどのように通知を送信しますか?まず、java.util.Observableクラスを継承して観察可能なクラスを生成する必要があり、次いで2つのステップが必要である.
  • は、setChanged()メソッドを呼び出し、ステータスが変更された事実をマークする.
  • は、次いで、notifyObservers()またはnotifyObservers()
  • の2つの方法のうちの1つを呼び出す.
  • 観察者はどのように通知を受け入れますか?観察者は更新の方法を実現したが,方法の署名は異なる:notifyObservers(Object arg).この時、2つの異なる効果を実現することができます.update(Observable o, Object arg)の属性が指定されていない場合、すなわちObjectオブジェクトの値のみが伝達される場合、この時点では、観察者に情報をプッシュしないことがデフォルトであるが、観察者は、観察者が提供するObservableの方法によって自発的にメッセージを取得することができる(ここでは、観察者の内部で観察者の参照を得る必要があることを示唆する).ここでgetのオブジェクトを指定すると、被観察者は観察者に情報をプッシュする.

  • なお、上記のObject法におけるupdate()パラメータは、被観察者におけるObjectnotifyObservers(Object o)パラメータと対応している.
    以上紹介した情報を利用して,以上のコードを書き換える.
    public class LovelyGirl extends Observable {
        private String eatState = "Inexact";
        private String studyState = "Inexact";
    
        public void setEatState(String eatState) {
            this.eatState = eatState;
    
        }
    
        public void setStudyState(String studyState) {
            this.studyState = studyState;
        }
    
        public String getEatState() {
            return eatState;
        }
    
        public String getStudyState() {
            return studyState;
        }
    
        public void stateChanged() {
            setChanged();
            notifyObservers();
        }
    }
    

    ここではパラメータなしのObject法を用いたが,これは,アクティブにプッシュしない方式を採用したことを意味する.また、ここでのnotifyObservers()は、setChanged()クラスで実現される方法であり、この方法の役割は、ステータスが変化した事実をマークすることであり、この関数を呼び出すだけで、被観察者が最新のステータスを観察者に通知することができる.
    public class FansOne implements Observer {
    
        private Observable observable;
    
        public FansOne(Observable observable) {
            this.observable = observable;
            observable.addObserver(this);
        }
    
        @Override
        public void update(Observable o, Object arg) {
            if (o instanceof LovelyGirl) {
                LovelyGirl girl = (LovelyGirl) o;
                System.out.println("eatState : " + girl.getEatState() +
                        " studyState : " + girl.getStudyState());
            }
        }
    }
    

    ここではObservableの方法をここに書いた.観察者に被観察者オブジェクトを引用した以上、追加した方法を主関数に入れる必要はないからだ.このときメイン関数のコードと出力結果を見てみましょう
    public class Client {
        public static void main(String[] args) {
            LovelyGirl girl = new LovelyGirl();
            FansOne fansOne = new FansOne(girl);
    
            girl.setEatState("I am eating...");
        }
    }
    
    
    eatState : I am eating... studyState : Inexact
    
    addObserver()に内蔵されたオブザーバーモードを利用すると、私たちが自分で書いたコード量が大幅に減少し、論理もより明確になります.しかし、Javaの内部でJavaを1つのクラスに設定するのは欠点があると思います.Observableは多重継承を許さないため、Javaの多重化能力を制限しています.