瞭解23種設計模式之觀察者模式

一,什麼是觀察者模式。

Observer模式是行爲模式之一,它的作用是當一個對象的狀態發生變化時,能夠自動通知其他關聯對象,自動刷新對象狀態。

Observer模式提供給關聯對象一種同步通信的手段,使某個對象與依賴它的其他對象之間保持狀態同步。

二,觀察者模式的結構。

三,觀察者模式的角色和職責

Subject(被觀察者)

     被觀察者的對象。當需要被觀察的狀態發生變化時,需要通知隊列中所有觀察者對象。Subject 需要維持(通知,刪除,添加) 一個觀察者對象的隊列列表。

ConcreteSubject

      被觀察者的具體實現。包含一些基本的屬性狀態及其他操作。

Observer (觀察者)

      接口或抽象類。當Subject 的狀態發生變化時,Observer 對象將通過一個 callback函數得到通知。

ConcreteObserver

    觀察者的具體實現。得到通知後將完成一些具體的業務邏輯處理。

 具體 jdk -api:

被 觀察者 繼承 Observble

觀察者 實現 Observer 接口

 

觀察者模式的典型應用

Observer 模式的典型應用

--偵聽事件驅動程序設計中的外部事件

--偵聽/監視某個對象的狀態變化

--發佈者/訂閱者(publisher/subscriber)模型中,當一個外部事件(新的產品,消息的出現等等)被觸發。通知郵件列表中的訂閱者。

 

四:例子代碼實現

此類表示模型視圖範例中的 observable 對象,或者說“數據”。可將其子類化,表示應用程序想要觀察的對象。

一個 observable 對象可以有一個或多個觀察者。觀察者可以是實現了 Observer 接口的任意對象。一個 observable 實例改變後,調用 ObservablenotifyObservers 方法的應用程序會通過調用觀察者的 update 方法來通知觀察者該實例發生了改變。

未指定發送通知的順序。Observable 類中所提供的默認實現將按照其註冊的重要性順序來通知 Observers,但是子類可能改變此順序,從而使用非固定順序在單獨的線程上發送通知,或者也可能保證其子類遵從其所選擇的順序。

注意,此通知機制與線程無關,並且與 Object 類的 wait 和 notify 機制完全獨立。

新創建一個 observable 對象時,其觀察者集是空的。當且僅當 equals 方法爲兩個觀察者返回 true 時,才認爲它們是相同的。(來自 jdk --api)

4.1.被觀察者

/**
 * @ClassName Person
 * @Description  繼承 Observable 表示可以被觀察的
 *
 * @Version 1.0
 **/
public class Person extends Observable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        //當 name 屬性改變,  標記此 被觀察 對象爲已改變的對象;現在 hasChanged 方法將返回 true。默認爲true。
        this.setChanged();
        // 通知 觀察者
        this.notifyObservers();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;

        //當 name 屬性改變, 設置爲 true ,默認爲true.  標記此 被觀察 對象爲已改變的對象;現在 hasChanged 方法將返回 true。
        this.setChanged();
        // 通知 觀察者
        this.notifyObservers();
    }
}

4.2 觀察者

/**
 * @ClassName MyObServer
 * @Description 觀察者, 一個可在觀察者要得到 observable 對象更改通知時可實現 Observer 接口的類。
 * @Version 1.0
 **/
public class MyObServer  implements Observer {

    /**
     *只要改變了 observable 對象就調用此方法。應用程序調用 Observable 對象的 notifyObservers 方法,以便向所有該對象的觀察者通知此改變。
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("對象發生改變");
    }
}

4.3 測試

public class Test {
    public static void main(String[] args) {
        Person person =new Person();
        //註冊1號觀察者
        person.addObserver(new MyObServer());
        //註冊2號觀察者
        person.addObserver(new MyObServer());
        person.setName("張三");
    }
}

五, 實際應用實現。

定義一個消息者對象

/**
 * @ClassName Article
 * @Description TODO
 * @Version 1.0
 **/
public class Article {
    private String articleTitle;
    private String articleContent;

    public String getArticleTitle() {
        return articleTitle;
    }

    public void setArticleTitle(String articleTitle) {
        this.articleTitle = articleTitle;
    }

    public String getArticleContent() {
        return articleContent;
    }

    public void setArticleContent(String articleContent) {
        this.articleContent = articleContent;
    }
}

定義一個被偵聽/監視  消息者對象的狀態變化,發佈者/訂閱者(publisher/subscriber)模型中,當一個外部事件(新的產品,消息的出現等等)被觸發。通知郵件列表中的訂閱者。

/**
 * @ClassName BlogUser
 * @Description TODO
 * @Version 1.0
 **/
public class BlogUser extends Observable {


    public void publishBlog(String articleTitle, String articleContent) {
        Article art = new Article();
        art.setArticleTitle(articleTitle);
        art.setArticleContent(articleContent);
        this.setChanged();
        this.notifyObservers(art);

    }
}

定義個 觀察者 ,相當於訂閱者。

/**
 * @ClassName MyObServer
 * @Description 觀察者, 一個可在觀察者要得到 observable 對象更改通知時可實現 Observer 接口的類。
 * @Version 1.0
 **/
public class MyObServer  implements Observer {

    /**
     *只要改變了 observable 對象就調用此方法。應用程序調用 Observable 對象的 notifyObservers 方法,以便向所有該對象的觀察者通知此改變。
     * @param o
     * @param arg
     */
    @Override
    public void update(Observable o, Object arg) {
        Article art = (Article) arg;
        System.out.println("博主發表了文章");
        System.out.println("博客標題爲:"+art.getArticleTitle());
        System.out.println("博客內容爲:"+art.getArticleContent());
    }
}

測試

/**
 * @ClassName Test
 * @Version 1.0
 **/
public class Test {
    public static void main(String[] args) {

       Article art = new Article();
       BlogUser blogUser = new BlogUser();
       blogUser.addObserver(new MyObServer());
       blogUser.publishBlog("博客上線了","大家來訪問");
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章