1. 程式人生 > >Android之觀察者/被觀察者模式Observer/Observable

Android之觀察者/被觀察者模式Observer/Observable

Android之觀察者Observer初探

知識點:

1、Android觀察者模式的簡介;

2、Observer和Observable的使用例項;

3、(abstract)抽象類和抽象方法的使用;

4、新名詞記錄

{

abstract:抽象關鍵詞

}

最近一直在看著觀察者模式的rxjava/rxandroid,但是我卻忽略了在Java中,也是有這個觀察者的。這也是我在一個專案中偶然看到的一個名詞,然後我就去搜索著來看了,不看不知道,一看嚇一跳,原來這裡頭有這麼深的水啊。只怪自己閱歷不夠了。

觀察者模式:簡單來說,就是當物件A對物件B進行進行了類似“訂閱”關係,當物件B的資料發生改變時,就要通知物件A進行相應。很簡單也很好理解。Android中的觀察者需要實現Observer介面,當資料發生改變時,觀察者的update()方法就會被呼叫,被觀察者繼承Observable類,在資料發生改變時,需要呼叫setChanged(); this.notifyObservers(obj);這兩個方法才可以通知觀察者:你想要知道的資料發生了變化了。

在學習這個觀察者模式的時候,腦袋突然開竅了,順便加固了一把抽象類/抽象方法的使用,之前看了N多的關於abstract關鍵字的學習,但是苦於一直沒有能夠真正的理解abstract關鍵的實際使用用途,只停留在了知識層面,木有應用。

今天弄這個觀察者模式的時候,想著我要把資料如何在單元測試中打印出來的問題時,我寫了一個abstract抽象方法,然後然後然後我就懂了這個要怎麼用了。實在可喜可賀啊!!!

好了,廢話不多說了,下面直接上程式碼,我都在程式碼裡頭做了註釋了,各位看官請直接看下面的程式碼。

首先定義一個繼承Observable的被觀察者LoginOutObservable.java抽象類。

package com.yaojt.sdk.java.observer;

import java.util.Observable;

/**
 * desc:被觀察者類,被觀察者如果資料發生變化,則需要通知觀察者,資料發生了改變,需要做相應的操作
 * <p>
 * author:kuyu.yaojt (tanksu)
 * <p>
 * email:[email protected]
 * <p>
 * blog:http://blog.csdn.net/qq_16628781
 * <p>
 * date:17/3/16
 */

public abstract class LoginOutObservable extends Observable {
    private String userName = "admin";

    /**
     * 設定是否登出,如果是,則需要通知觀察者
     *
     * @param isLoginOut isLoginOut
     */
    public void setLoginOut(boolean isLoginOut) {
        if (isLoginOut) {
            String data = "被觀察者告訴你:你已經退出登入,請重新登入!";
            /* 注意注意注意:下面這兩個方法是要同時呼叫的,否則不會通知觀察者資料發生了變化 */
            setChanged();
            this.notifyObservers(data);
            onUserLoginOut("這是在被觀察者內部呼叫的方法:" + data);
        }
    }

    /**
     * 設定使用者名稱,如果使用者名稱和上次的不一樣,則需要通知觀察者
     *
     * @param name name
     */
    public void setUserName(String name) {
        if (!name.equals(userName)) {
            this.userName = name;
            String data = "被觀察者告訴你:使用者名稱已經改變了!新的名字為:" + name;
            /* 注意注意注意:下面這兩個方法是要同時呼叫的,否則不會通知觀察者資料發生了變化 */
            setChanged();
            this.notifyObservers(data);
            onUserNameChanged("這是在被觀察者內部呼叫的方法:" + data);
        }
    }

    /**
     * 當用戶名字發生改變時,用於在本類中將資料打印出來
     * <p>
     * 感悟:
     * 抽象方法,凡是繼承此類的子類,都需要重寫此方法
     * 但是我們可以再本類裡呼叫此方法,然後例項化此類的時候,要求實現類實現本類裡頭的抽象方法
     *
     * @param newUserName
     */
    public abstract void onUserNameChanged(String newUserName);

    /**
     * 當用戶登出時,在本類中用於將資料打印出來
     * <p>
     * 感悟:
     * 抽象方法,凡是繼承此類的子類,都需要重寫此方法
     * 但是我們可以再本類裡呼叫此方法,然後例項化此類的時候,要求實現類實現本類裡頭的抽象方法
     *
     * @param message message
     */
    public abstract void onUserLoginOut(String message);
}

然後再定義一個繼承Observer的觀察者LoginoutObserver.java。

package com.yaojt.sdk.java.observer;

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

/**
 * desc:
 * <p>
 * author:kuyu.yaojt (tanksu)
 * <p>
 * email:[email protected]
 * <p>
 * blog:http://blog.csdn.net/qq_16628781
 * <p>
 * date:17/3/16
 */

public abstract class LoginoutObserver implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        /* 當被觀察者因為資料發生了改變,並通知了相關的觀察者後,觀察者將會呼叫此方法進行相應
        * 我們這裡呼叫的是本地的抽象方法進行資料輸出 */
        onDataChanged("觀察者從被觀察者中的訊息:", arg);
    }

    /**
     * 這裡給出一個抽象方法給實現類實現,然後我們會在updat()方法被呼叫的時候,呼叫這個方法,給實現類相應
     *
     * @param message message
     * @param object  object
     */
    public abstract void onDataChanged(String message, Object object);
}
最後我們就可以在單元測試裡頭進行測試了,如果又不熟悉IDE上面如何進行單元測試的,請看這篇文章點選開啟連結,我就不細講了。
@Test
    public void observerTest() {
        /* 被觀察者:登出/修改使用者名稱類,例項 */
        LoginOutObservable loginOutObservable = new LoginOutObservable() {
            @Override
            public void onUserNameChanged(String newUserName) {
                printer(newUserName);
            }

            @Override
            public void onUserLoginOut(String message) {
                printer(message);
            }
        };
        /*觀察者1:並實現了觀察者類的抽象方法,實現在這裡進行資料的列印輸出 */
        LoginoutObserver loginoutObserver1 = new LoginoutObserver() {
            @Override
            public void onDataChanged(String message, Object object) {
                printer("我是觀察者1-->" + message + "," + object.toString());
            }
        };
        /*觀察者2:並實現了觀察者類的抽象方法,實現在這裡進行資料的列印輸出 */
        LoginoutObserver loginoutObserver2 = new LoginoutObserver() {
            @Override
            public void onDataChanged(String message, Object object) {
                printer("我是觀察者2-->message:" + message + "," + object.toString());
            }
        };
        LoginoutObserver loginoutObserver3 = new LoginoutObserver() {
            @Override
            public void onDataChanged(String message, Object object) {
                printer("我是觀察者3-->message:" + message + "," + object.toString());
            }
        };
        /**
         * 這裡像是被觀察者訂閱了觀察者,看起來是有點彆扭的哈;
         * 就像和反射裡面呼叫invoke方法:method.invoke(obj, args);
         * 具體可以參考這篇文章:
         * 但是不要被混淆了,最好記的一點就是:外國人說話看起來都是和中文"反過來"的
         */
        loginOutObservable.addObserver(loginoutObserver1);
        loginOutObservable.addObserver(loginoutObserver3);
        loginOutObservable.addObserver(loginoutObserver2);

        /* 這裡是模擬被觀察者登出操作,登出了必須要通知使用者重新登入啊 */
        loginOutObservable.setLoginOut(true);
        /* 這裡是模擬被觀察者修改了使用者名稱操作,導致前後使用者名稱不一致而引起資料變化了 */
        loginOutObservable.setUserName("tanksu");
    }

public void printer(String content) {
        System.out.println(content);
    }

執行的結果如下:



如果你夠細心的話,你會發現一個問題:我們觀察者new的時候,是按著1->2->3的順序來的,但是怎麼資料改變時,呼叫的觀察者方法卻是反過來的呢,變成了2->3->1。猛地一看,發現這是我進行“訂閱”被觀察者的倒序呢。這裡我們可以得到一個結論:在資料發生改變時,被觀察者通知觀察者的循序是遵循“先訂閱後通知”的循序。這裡要注意一下。

以上就是我的個人簡介。

如果有任何疑問,請及時與我聯絡。謝謝。




相關推薦

Android觀察/觀察模式Observer/Observable

Android之觀察者Observer初探 知識點: 1、Android觀察者模式的簡介; 2、Observer和Observable的使用例項; 3、(abstract)抽象類和抽象方法的使用; 4、新名詞記錄 { abstract:抽象關鍵詞 } 最近一直在看著觀察

Java觀察模式 : Observer / Observable

/** Java觀察者模式的場景:一個女孩洗澡,被很多男孩偷看。 女孩洞察後,搜尋壞男孩,然後繼續洗澡。 三個類:Boy,Girl還有主類MainClass。 */ /* 男孩 Boy.java */ import java.util.Observable; impor

必須做作業三:某Android端點餐App中觀察模式解析

onclick https 直接 tro lstat strong set lis drag 該項目還在開發中,目前開發了原型界面,是為了實現顧客從點餐到付款的全行為流程。並且提供菜品的詳情頁面和其他服務接口。 在此就以點餐界面的實現為例,分析該項目的觀察者模式 一、模

23種設計模式---觀察模式(Observer Factory)

1.觀察者模式(行為型模式) 觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態發生變化時,會通知所有的觀察者物件,使它們能夠自己更新自己。 2.觀察者模式結構圖 3.觀察者模式結構圖分析 Subject類,可理解為主題或抽象通知者

Android官方架構元件LiveData: 觀察模式領域二三事

本文是 《Android Jetpack 官方架構元件》 系列的最後一篇文章,和一些朋友的觀點不同的是,我認為它是 最重要 的核心元件,因為 LiveData本身很簡單,但其代表卻正是 MVVM 模式最重要的思想,即 資料驅動檢視(也有叫觀察者模式、響應式等)——這也是擺脫 順序性程式設

面試問設計模式?不要怕看這裡:觀察模式

本系列: 上一篇中,我給大家詳細講解了一下工廠模式以及面試中可能會被問到的關鍵點,我們先來溫習溫習。 工廠模式的關鍵點: 一、工廠模式分為簡單工廠,工廠和抽象工廠 二、三種工廠的實現是越來越複雜的 三、簡單工廠通過構造時傳入的標識來生產產品,不同產品都在同一個工廠

設計模式----行為型模式觀察模式(Observer Pattern)

/** * 天氣主題(可觀察者/目標) * @author mjs * @version 1.0.0 * @filename WeatherData.java * @time 2017-3-9 下午8:26:48 * @copyright(C) 2017 **********有限公司 */ pa

面向物件設計模式---觀察模式(Observer Pattern)

今天更新的設計模式是觀察者模式。剛才稍微去看了一眼Web前端開發,很炫!很炫! 對於這個觀察者模式,我就直接開門見山地直接放出定義和UML類圖,後面再解釋。 觀察者模式的定義如下: 觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽一個主題物件。這個主題物

Java設計模式觀察模式(Observer Pattern)

Observer Pattern 是一種常用的設計模式,它是一種事件監聽模型。該模式有兩個角色,一個是Subject, 另一個是Observer。Subject 儲存有多個Observer的引用,一旦特定的事件發生,Subject會通知它所有的Observer,Observ

androidContentObserver內容觀察的使用

在跟著一個教程做手機衛士的時候,裡面用到了ContentObserver,以前沒接觸過,根據網上的資料整理了一下,還算明白。     ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引起的資料庫的變化,繼而做一些相應的處理,它類似於   資料庫技術中

android 頁面訊息傳遞,觀察模式處理,打造純粹的訊息傳遞。

現實的開發過程中大家都會用到很多頁面與頁面之間的訊息傳遞,方法有很多,觀察者模式,EventBus,廣播,intent,很多很多種方式可以實現。今天我要提一提利用觀察者模式進行頁面之間的訊息傳遞與接收。 首先定義一個用於通知訊息的介面,ObserverListener /

Android觀察模式Observable)的理解

對於觀察者模式還是第一次接觸,今天在上網看了些資料瞭解了一下,大意瞭解了…… 定義:“定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變的時候,所有依賴於它的物件都將得到通知,並自動更新”,這就是所謂的觀察者模式,照意思理解那麼就一定會有觀察者和被觀察者了,在Jav

觀察模式(訂閱與釋出模式),史上最簡單的觀察觀察理解;

說道觀察者模式,網路上有很多說法,什麼一對多了,還有什麼主題了,角色了,看著都煩,雖說要用官方的話來描述一些東西,但是太官方的話,有幾個能看得懂,特別是菜鳥,小白估計就直接看不下去了。這裡,我用最簡單的方式,幫助大街理解觀察者模式,我先用最通俗的方式來講解並附上程式碼,之後

研磨設計模式 觀察模式(Observer) 3——跟著cc學設計系列

12.3  模式講解 12.3.1  認識觀察者模式 (1)目標和觀察者之間的關係        按照模式的定義,目標和觀察者之間是典型的一對多的關係。        但是要注意,如果觀察者只有一個,也是可以的,這樣就變相實現了目標和觀察者之間一對一的關係,這也使得在處理一

Unity/C#基礎複習(5) 淺析觀察、中介模式在遊戲中的應用與delegate原理

參考資料 【1】 《Unity 3D指令碼程式設計 使用C#語言開發跨平臺遊戲》陳嘉棟著 【2】 @張子陽【C#中的委託和事件 - Part.1】 http://www.tracefact.net/tech/009.html 【3】 @張子陽【C#中的委託和事件 - Part.2】 http://www.t

觀察模式(Observer Pattern)(二):HeadFirst中的氣象站的實現

att dex mov min first return 狀態 size sdi 1 觀察者模式的原理,首先由一個主題,當主題發送變化的時候,通知該主題的訂閱者 按照上面的分析我們來進行設計 1.抽象主題Subject public interface Subject {

Java 設計模式系列(十六)觀察模式(Observer)

for out 其中 如果 observer 業務 ets 同時 hang Java 設計模式系列(十六)觀察者模式(Observer) 觀察者模式是對象的行為模式,又叫發布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽

【編程思想】【設計模式】【行為模式Behavioral】觀察模式Observer

setting notify tput pes env observer 設計模式 mod pre Python轉載版 https://github.com/faif/python-patterns/blob/master/behavioral/observer.py

設計模式觀察模式--Observer

sub 系統調用 特點 xiaomi ttr root comm wrap 切換 一、什麽是觀察者模式 1、生活中的觀察者模式 1、警察抓小偷 在現實生活中,警察抓小偷是一個典型的觀察者模式「這以一個慣犯在街道逛街然後被抓為例子」,這裏小偷就是被觀察者,各個幹

RxJava2(二)五種觀察

五種被觀察者為Observable,Flowable,Single,Completable,Maybe。 五種被觀察者可通過toObservable,toFlowable,toSingle,toCompletable,toMaybe相互轉換 Observable 一簡介 1.Obse