Android觀察者模式隨記--(一)

前言

對于設計模式的學習,作者一開始是拒絕的。因為作者的Java基礎和Android基礎很爛。想著補一下Java坑,做做App練習,鞏固基礎,但是糾結了半天還是選擇看看設計模式,畢竟還年輕,瞎搞唄。大致瀏覽了一下設計模式,發(fā)現(xiàn)確實很難懂。借著這個機會,我就想把自己的設計模式學習歷程記錄下來,希望能對迷茫的朋友有所幫助。當然了,新手上路,錯誤難免,請多指教!

觀察者模式

  • 定義

裝逼式:定義對象之間一種一對多的依賴關系,使得每當一個對象改變狀態(tài),則所有依賴于它的對象都會得到通知并被自動更新。
正常點說:幾個對象去觀察一個對象的狀態(tài),這一個對象狀態(tài)發(fā)生改變時,會通知觀察它的那幾個對象,這幾個對象觀察到被觀察對象狀態(tài)發(fā)生變化了,然后自己就會做一些事情。當然,從這里就引出了兩個關鍵類——Observer(觀察者)、Subject(被觀察者)

Observer-Subject關系圖
  • 應用

當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。
比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。

  • 實際操作

意圖:定義對象間的 一對多 的關系。
用途:目標對象的狀態(tài)改變,所有的依賴對象(觀察者對象)得到通知。
實例:1、拍賣的時候,拍賣師觀察最高標價,然后通知給其他競價者競價。 2、西游記里面悟空請求菩薩降服紅孩兒,菩薩灑了一地水招來一個老烏龜,這個烏龜就是觀察者,他觀察菩薩灑水這個動作。 3、顧客在訂奶站定牛奶,訂奶站的人員只需保證牛奶送到訂奶站,并通知顧客前來領取而不管顧客會把牛奶拿去喝還是洗臉;顧客接到訂奶站的工作人員的通知,就去取牛奶,但并不關心他們是怎樣把牛奶送到訂奶站的。4、快遞員送快遞,打電話叫顧客領包裹。等等。
利弊: 利:1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發(fā)機制。弊:1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目標之間有循環(huán)依賴的話,觀察目標會觸發(fā)它們之間進行循環(huán)調用,可能導致系統(tǒng)崩潰。 3、觀察者模式?jīng)]有相應的機制讓觀察者知道所觀察的目標對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標發(fā)生了變化(理論的東西太死板,不好直觀地反映問題,遇到具體的代碼再說吧。)。
注意:
(1)在抽象類里有一個 ArrayList 存放觀察者們。
(2)JAVA 中已經(jīng)有了對觀察者模式的支持類。JDK中提供的java.util.Observable實現(xiàn)類和java.util.Observer接口。
(3)避免循環(huán)引用。
(4)如果順序執(zhí)行,某一觀察者錯誤會導致系統(tǒng)卡殼,一般采用異步方式。

  • 使用

Android中的觀察者實現(xiàn)Observer接口,被觀察者繼承Obervable類

  • 觀察者MyObserver實現(xiàn)Observer 接口。
  • 被觀察者MyObservable繼承Observable 類。
  • 觀察者MyObserver向被觀察者 MyObservable 訂閱事件(將觀察者MyObserver添加到被觀察者MyObservable里面去)。
  • 被觀察者MyObservable數(shù)據(jù)有改變,通知觀察者MyObserver相應的數(shù)據(jù)有改變,請作出相應的操作。(核心操作)
  • 觀察者MyObserver向被觀察者 MyObservable取消訂閱事件(將觀察者MyObserver從被觀察者MyObservable中移除)。
  • 入坑

看了部分資料,踩坑一步一步寫了點:

觀察者類(Object):

/**
 * @author bruno
 * @date: 2016/6/1
 *
 * TODO <>觀察者類,實現(xiàn)Observer的接口。</>
 */
public abstract class MyObserver implements Observer {
    @Override
    public void update(Observable observable, Object data) {
    }
}

問:觀察者必須是抽象類么?

被觀察類(Subject):

/**
 * @author bruno
 * @date: 2016/6/1
 *
 * TODO <>被觀察者類,繼承Observable</>
 */

public class MyObservable extends Observable {

    //單例模式
    private volatile static MyObservable instance = null;

    private MyObservable() {
    }

    public static MyObservable getInstance() {
         if (instance == null) {
             synchronized (MyObservable.class) {
                 if (instance == null) {
                     instance = new MyObservable();
                 }
             }
         }
        return instance;
    }

    public void notifyDataChange(Data data) {
        //這是Observable的兩個重要方法,數(shù)據(jù)改變和觀察者的改變
        setChanged();
        notifyObservers(data);
    }
}

被觀察者類直接繼承Observable就行,這里使用了單例模式(雙重校驗鎖)。關于單例模式,了解過一點,但是現(xiàn)在沒怎么運用,所以還只是停留在概念上。這里有一篇不錯的文章,如有問題,還望讀者指出。

Data類:

/**
 * @author bruno
 * @date: 2016/6/1
 *
 * TODO <>Data數(shù)據(jù)類</>
 */
public class Data {

    private int dataChange;

    public Data() {
    }

    public int getDataChange() {
        return dataChange;
    }

    public void setDataChange(int dataChange) {
        this.dataChange = dataChange;
    }
}

這個沒什么解釋的,模擬數(shù)據(jù)。

Activity:

public class MainActivity extends AppCompatActivity {

    private MyObserver myObserver = new MyObserver() {
        @Override
        public void update(Observable observable, Object data) {
            super.update(observable, data);
            //觀察者接受到被觀察者的通知,來更新自己的數(shù)據(jù)操作。
            Data mData = (Data) data;
            Log.e("MainActivity",  "mData+++++++++++++" + mData.getDataChange());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //模擬被觀察者數(shù)據(jù)改變,更新數(shù)據(jù)。
        Data mData = new Data();
        mData.setDataChange(0);
        MyObservable.getInstance().notifyDataChange(mData);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //觀察者往被觀察者中添加訂閱事件。
        MyObservable.getInstance().addObserver(myObserver);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //觀察者從被觀察者隊列中移除
        MyObservable.getInstance().deleteObserver(myObserver);
    }

}

初探這坑不淺,還得慢慢踩。請多指教!

  • 參考資料

Android 中的觀察者模式
Android 實現(xiàn) listener: Observer pattern (觀察者模式)
歡迎大家討論交流指出問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容