Javaデザインモード--オブザーバーモード
6312 ワード
学校にはとてもかわいい女の子がいて、多くの男の子が彼女のファンの仲間入りをして、みんなは先を争って彼女の情報を集めました.この时、女の子のルームメイト、同級生はすべて彼女に文句を言い始めて、彼女も罪悪感を感じて、周りの友达に迷惑をかけたと感じました.そこで、彼女は自分の状態を公開することにした.前提は彼女の周りの人に迷惑をかけないことだ.最初、彼女は自分の毎日の食事と勉强の状态を公开して、彼女のファンが彼女のここで登录する限り、苦労せずに自分の动态の情报を受け取ることができて、これはファンにとってまるで天の大きい良いニュースです...この时1人のプログラマーが通りかかって、この现象を见て、霊光がきらめいて、これは観察者のモードです.まず、女の子を1つのクラスに抽象化して、彼女の行為は私たちも方法を書くことができて、そこで次の2つのクラスがあります.
ここでは、女の子をインタフェースとして書きました.結局、人はいつも異思遷に会うのですか.もし学校にきれいな女の子が来たら?では、
インタフェースがあれば、多くのファンがこのインタフェースを実現し、最新情報を得ることができます.例えばファンAとファンB-
はい、すべての準備はもう終わりましたが、この時はもうお昼になりました.女の子は言いました.私は食事を始めます.例えば、下のように.
印刷結果は次のとおりです.
実は、上の例は私たちがよく言っている観察者パターンです.オブザーバモードは、オブジェクト間の一対のマルチ依存性を定義し、オブジェクトの状態が変化すると、すべての依存者が通知を受け取り、自動的に更新されます.天気予報購読システム、新聞購読システムなど、生活の中で多くの場所で使われています.
上の例では、プッシュ機能しか書いていないので、ファンが自分から情報を得ようとしたら?もしあるファンがあなたの学習状態に興味がなく、もう学習に関する情報を送りたくないと言ったら.では、どのように改善すればいいのでしょうか.ちょうどこの機会に、オブジェクトを観察者にするにはどうすればいいですか?観察者インタフェースが実装され、 観察者はどのように通知を送信しますか?まず、 は、 は、次いで、 の2つの方法のうちの1つを呼び出す.
観察者はどのように通知を受け入れますか?観察者は更新の方法を実現したが,方法の署名は異なる:
なお、上記の
以上紹介した情報を利用して,以上のコードを書き換える.
ここではパラメータなしの
ここでは
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()
のnotifyObservers(Object arg)
.この時、2つの異なる効果を実現することができます.update(Observable o, Object arg)
の属性が指定されていない場合、すなわちObject
オブジェクトの値のみが伝達される場合、この時点では、観察者に情報をプッシュしないことがデフォルトであるが、観察者は、観察者が提供するObservable
の方法によって自発的にメッセージを取得することができる(ここでは、観察者の内部で観察者の参照を得る必要があることを示唆する).ここでget
のオブジェクトを指定すると、被観察者は観察者に情報をプッシュする.なお、上記の
Object
法におけるupdate()
パラメータは、被観察者におけるObject
のnotifyObservers(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
の多重化能力を制限しています.