溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

觀察者的使用

發(fā)布時間:2020-08-02 01:26:09 來源:網(wǎng)絡(luò) 閱讀:547 作者:海太帥 欄目:移動開發(fā)

觀察者模式

二話不說,上來就是定義

定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)送改變時,所有依賴于它的對象都能得到通知并被自動更新

這個好像還好理解那么一點點,不過還是先來講個情景,

天氣預(yù)報的短信服務(wù),一旦付費訂閱,每次天氣更新都會向你及時發(fā)送

其實就是我們無需每時每刻關(guān)注我們感興趣的東西,我們只需要訂閱它即可,一旦我們訂閱的事務(wù)有變化了,被訂閱的事務(wù)就會即時的通知我們

我們來看一下觀察者模式的組成:


  • 觀察者,我們稱它為Observer,有時候我們也稱它為訂閱者,即Subscriber

  • 被觀察者,我們稱它為Observable,即可以被觀察的東西,有時候還會稱之為主題,即Subject

至于觀察者模式的具體實現(xiàn),java里為我們提供了Observable類和Observer接口供我們快速實現(xiàn)該模式,但是這里為了加深印象,不用這個兩個類,以下是觀察者模式的代碼實現(xiàn):

1、首先我們定義一個的接口,里面是觀察者需要做的三件事:

public interface ObjectAble {


public void add(ObjectSerType type, ObjectServer obj);//添加訂閱


public void remove(ObjectSerType type, ObjectServer obj);//取消訂閱


void notifyDataChange(ObjectSerType type, Object... objs);//發(fā)送訂閱內(nèi)容

}

2、當(dāng)主題發(fā)生變化的時候,需要通知觀察者來做出響應(yīng),還需要一個onRecever方法,具體實現(xiàn)如下

public interface ObjectServer {

void onRecever(Object...obj);

}

3、定義觀察者類型的枚舉類,這是表示觀察者的類型,當(dāng)觸發(fā)ObjectAble 接口中的notifyDataChangee(ObjectSerType type, Object... objs)方法時,即主題發(fā)生變化,所有類型為type的已訂閱的觀察者會被觸發(fā)。

package com.example.testobjectserver;

public enum ObjectSerType{

a,b,c,d

}

4、實現(xiàn)ObjectAble接口,為每個方法添加邏輯

package com.example.testobjectserver;


import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;


import android.util.Log;


public class ObjectAbleImpelet implements ObjectAble {

public static ArrayList<HashMap<ObjectSerType, ObjectServer>> ObjectServerList = new ArrayList<HashMap<ObjectSerType, ObjectServer>>();


static ObjectAbleImpelet instance = null;


public static ObjectAbleImpelet getInstance() {

synchronized (ObjectAbleImpelet.class) {

if (instance == null)

instance = new ObjectAbleImpelet();

}

return instance;

};


@Override

public void add(ObjectSerType type, ObjectServer obj) {

if (type == null && obj == null)

throw new NullPointerException("ObjectSerType or ObjectServer can not null");

synchronized (ObjectServerList) {

HashMap<ObjectSerType, ObjectServer> map = new HashMap<ObjectSerType, ObjectServer>();

map.put(type, obj);

ObjectServerList.add(map);

Log.e("", "ObjectServerList>>>" + ObjectServerList);

}

}


@Override

public void remove(ObjectSerType type, ObjectServer obj) {

for (HashMap<ObjectSerType, ObjectServer> map : ObjectServerList) {

Log.e("", "type>>>" + type);

if(map.get(type).equals(obj)){

ObjectServerList.remove(map);

Log.e("", "obj>>>" + obj);

break;

}

}

}


@Override

public void notifyDataChange(ObjectSerType type, Object... objs) {

for (int i = 0; i < ObjectServerList.size(); i++) {

HashMap<ObjectSerType, ObjectServer> map = ObjectServerList.get(i);

if (map.containsKey(type)) {

map.get(type).onRecever(objs);

}

}

}


}

5、測試:

package com.example.testobjectserver;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.TextView;


public class MainActivity extends Activity implements ObjectServer {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ObjectAbleImpelet.getInstance().add(ObjectSerType.a, this);//添加訂閱,類型為ObjectSerType.a, 類型由開發(fā)者定義

findViewById(R.id.button1).setOnClickListener(new OnClickListener() {


@Override

public void onClick(View v) {

// TODO Auto-generated method stub

ObjectAbleImpelet.getInstance().notifyDataChange(

ObjectSerType.a, "你好");//主題發(fā)生變化,觸            //發(fā)所有類型為ObjectSerType.a的觀察者調(diào)用onRecever方法

}

});

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}

        //主題變化后,觀察者的回調(diào)

@Override

public void onRecever(Object... obj) {

Log.e("", "我是觀察者?。?!" + (String) obj[0]);

((TextView) findViewById(R.id.textView1)).setText("" + (String) obj[0]);

}


@Override

protected void onDestroy() {

//無論如何,當(dāng)退出activity,該activity中的觀察者需要被回收,不然會導(dǎo)致觀察者容器中的觀察者

    //對象越來越多

ObjectAbleImpelet.getInstance().remove(ObjectSerType.a, this);

super.onDestroy();

}


}

6、如下圖所示:進入activity注冊類型為a的觀察者,當(dāng)點擊按鈕,觸發(fā)onRecive回調(diào),更新ui;退出activity時注銷觀察者。該觀察者完成使命
觀察者的使用


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI