<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 51, comments - 17, trackbacks - 0, articles - 9
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    java模式之觀察者模式

    Posted on 2007-03-24 17:03 chenweicai 閱讀(878) 評(píng)論(0)  編輯  收藏
     觀察者模式是對(duì)象的行為模式,顧名思義,即存在觀察者和被觀察者。?觀察者模式可以讓多個(gè)觀察者同時(shí)監(jiān)聽同一個(gè)被觀察對(duì)象,當(dāng)被觀察對(duì)象發(fā)生變化時(shí),并通知所有觀察者,使各個(gè)觀察者能作出相應(yīng)的響應(yīng)。適當(dāng)?shù)剡\(yùn)用觀察者模式,能提高自身代碼的設(shè)計(jì)水平。

      觀察者模式理解和編碼都比較簡(jiǎn)單,通常包括以下步驟:

      1. 設(shè)計(jì)觀察者接口類;
      2. 觀察者類實(shí)現(xiàn)該接口;
      3. 設(shè)計(jì)被觀察者抽象類,該類中提供一些方法,如:添加觀察者對(duì)象,刪除觀察者對(duì)象,把事件通知給各個(gè)觀察者對(duì)象;
      4. 設(shè)計(jì)被觀察者類,繼承被觀察者抽象類,在該類中,可以根據(jù)需要在該類中,可以定義方法:被觀察者是否發(fā)生變化

      以上四步,即完成了觀察者模式的設(shè)計(jì)。下面代碼分類進(jìn)行描述以上步驟:

    package Observer;

    import java.util.Enumeration;
    import java.util.Vector;

    abstract public class Subject {

    ?private Vector observersVector = new java.util.Vector();
    ?
    ?public void attach(Observer observer){
    ??observersVector.addElement(observer);
    ??System.out.println("Attached an observer.");
    ?}
    ?
    ?public void detach(Observer observer){
    ??observersVector.removeElement(observer);
    ?}
    ?
    ?public void notifyObservers(){
    ??java.util.Enumeration enumeration = observers();
    ??while(enumeration.hasMoreElements()){
    ???System.out.println("Before notifying");
    ???((Observer)enumeration.nextElement()).update();
    ??}
    ?}
    ?
    ?public Enumeration observers(){
    ??return ((java.util.Vector)observersVector.clone()).elements();
    ?}
    }


    package Observer;

    public class ConcreteSubject extends Subject{

    ?private String state;
    ?
    ?public void change(String newState){
    ??state = newState;
    ??this.notifyObservers();
    ?}
    }


    package Observer;

    public interface Observer {

    ?void update();
    }


    package Observer;

    public class ConcreteObserver implements Observer{
    ?
    ?public void update(){
    ??System.out.println("I am notified.");
    ?}

    }


    package Observer;

    public class Client {

    ?private static ConcreteSubject subject;
    ?private static Observer observer1;
    ?private static Observer observer2;
    ?
    ?public static void main(String[] args){
    ??subject = new ConcreteSubject();
    ??observer1 = new ConcreteObserver();
    ??observer2 = new ConcreteObserver();
    ??
    ??subject.attach(observer1);
    ??subject.attach(observer2);
    ??
    ??subject.change("new state");
    ?}
    }


    運(yùn)行結(jié)果是:

    Attached an observer.
    Attached an observer.
    Before notifying
    I am notified.
    Before notifying
    I am notified.


    在java中提供了Observerable類和Observer接口來實(shí)現(xiàn)觀察者模式

    public class Observable
    extends Object

    此類表示模型視圖范例中的 observable 對(duì)象,或者說“數(shù)據(jù)”。可將其子類化,表示應(yīng)用程序想要觀察的對(duì)象(即被觀察者)。

    一個(gè) observable 對(duì)象可以有一個(gè)或多個(gè)觀察者。觀察者可以是實(shí)現(xiàn)了 Observer 接口的任意對(duì)象。一個(gè) observable 實(shí)例改變后,調(diào)用 ObservablenotifyObservers 方法的應(yīng)用程序會(huì)通過調(diào)用觀察者的 update 方法來通知觀察者該實(shí)例發(fā)生了改變。

    未指定發(fā)送通知的順序。Observable 類中所提供的默認(rèn)實(shí)現(xiàn)將按照其注冊(cè)的重要性順序來通知 Observers,但是子類可能改變此順序,從而使用非固定順序在單獨(dú)的線程上發(fā)送通知,或者也可能保證其子類遵從其所選擇的順序。

    注意,此通知機(jī)制與線程無關(guān),并且與 Object 類的 waitnotify 機(jī)制完全獨(dú)立。

    新創(chuàng)建一個(gè) observable 對(duì)象時(shí),其觀察者集合是空的。當(dāng)且僅當(dāng) equals 方法為兩個(gè)觀察者返回 true 時(shí),才認(rèn)為它們是相同的。

    public interface Observer

    一個(gè)可在觀察者要得到 observable 對(duì)象更改通知時(shí)可實(shí)現(xiàn) Observer 接口的類。?
    ?給個(gè)用java機(jī)制來實(shí)現(xiàn)觀察者模式的例子
    在java機(jī)制中Observable類相當(dāng)于抽象主題角色,我們定義具體主題角色來繼承該類
    Observer 接口相當(dāng)于抽象觀察者角色,我們定義具體觀察者角色來實(shí)現(xiàn)該接口
    所以這兩個(gè)抽象角色我們不用編寫了 只需編寫兩個(gè)具體角色

    //----具體觀察對(duì)象角色
    package Observer.javaObserver;

    import java.util.Observable;

    public class Product extends Observable{

    ?private String name;
    ?private float price;
    ?
    ?public String getName(){
    ??return name;
    ?}
    ?
    ?public void setName(String name){
    ??this.name = name;
    ??// 設(shè)置變化點(diǎn)
    ??setChanged();
    ??notifyObservers(name);//通知觀察者
    ?}

    ?public float getPrice() {
    ??return price;
    ?}

    ?public void setPrice(float price) {
    ??this.price = price;
    ??//設(shè)置變化點(diǎn)
    ??setChanged();
    ??notifyObservers(new Float(price));
    ?}
    ?
    ?public void saveToDb(){
    ??System.out.println("saveToDb");
    ?}
    }

    //------------ 兩個(gè)具體觀察者角色
    package Observer.javaObserver;

    import java.util.Observable;
    import java.util.Observer;

    public class NameObserver implements Observer {

    ?private String name = null;
    ?
    ?public void update(Observable obj, Object arg){
    ??if(arg instanceof String){
    ???name = (String)arg;
    ???System.out.println("NameObserver:name changed to " + name);
    ??}
    ?}
    }

    package Observer.javaObserver;

    import java.util.Observable;
    import java.util.Observer;

    public class PriceObserver implements Observer{

    ?private float price=0;
    ?
    ?public void update(Observable obj, Object arg){
    ??if(arg instanceof Float){
    ???price = ((Float)arg).floatValue();
    ???System.out.println("PriceObserver: price change to" + price);
    ??}
    ?}
    }

    //----測(cè)試程序

    package Observer.javaObserver;

    import java.util.Observer;

    public class Test {

    ?public static void main(String[] args){
    ??Product product = new Product();
    ??Observer nameObs = new NameObserver();
    ??Observer priceObs = new PriceObserver();
    ??
    ??product.addObserver(nameObs);
    ??product.addObserver(priceObs);
    ??
    ??product.setName("apple");
    ??product.setPrice(9.22f);
    ??
    ??product.setName("Apple");
    ??product.setPrice(9.88f);
    ??}
    }


    //---運(yùn)行結(jié)果

    NameObserver:name changed to apple
    PriceObserver: price change to9.22
    NameObserver:name changed to Apple
    PriceObserver: price change to9.88




    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品第一国产综合野| 亚洲黄片手机免费观看| 亚洲精品无码专区2| 四虎国产精品免费永久在线| 18亚洲男同志videos网站| 日韩免费观看的一级毛片| 成av免费大片黄在线观看| 亚洲成在人线电影天堂色| 亚洲精品A在线观看| 一级毛片免费毛片毛片| 久久国产精品成人免费| 51精品视频免费国产专区| 久久国产乱子伦精品免费看| 日韩精品无码免费专区午夜不卡| 色妞www精品视频免费看| 好看的电影网站亚洲一区| 国产美女在线精品免费观看| a级成人毛片免费图片| 亚洲欧美国产国产一区二区三区| 亚洲日产无码中文字幕| 夫妻免费无码V看片| 99久久精品免费精品国产| 免费一区二区三区在线视频| 亚洲剧情在线观看| 亚洲熟妇无码另类久久久| 永久黄网站色视频免费| free哆啪啪免费永久| 中国一级全黄的免费观看| 婷婷国产偷v国产偷v亚洲| 亚洲一级毛片视频| 亚洲伦理一区二区| 亚洲精品二区国产综合野狼| 亚洲 综合 国产 欧洲 丝袜| 无码人妻一区二区三区免费手机 | 亚洲日本香蕉视频| 一级毛片a免费播放王色电影 | 亚洲精品无码久久久久APP| 亚洲天天做日日做天天看| 亚洲成人一区二区| 四虎影视精品永久免费| 四虎免费大片aⅴ入口|