android中的Observer模式,是繼承自java的實(shí)現(xiàn),使用Observable類和Observer實(shí)現(xiàn)。
Observer模式定義對(duì)象間的一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí), 所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。JDK里提供的observer設(shè)計(jì)模式的實(shí)現(xiàn)由java.util.Observable類和 java.util.Observer接口組成。從名字上可以清楚的看出兩者在Observer 設(shè)計(jì)模式中分別扮演的角色:Observer是觀察者角色,Observable是被觀察目標(biāo)(subject)角色。
應(yīng)用場(chǎng)景
- 對(duì)一個(gè)對(duì)象狀態(tài)的更新,需要其他對(duì)象同步更新,而且其他對(duì)象的數(shù)量動(dòng)態(tài)可變。
- 對(duì)象僅需要將自己的更新通知給其他對(duì)象而不需要知道其他對(duì)象的細(xì)節(jié)。
優(yōu)缺點(diǎn)
observer模式的優(yōu)點(diǎn)
- Subject和Observer之間是松耦合的,分別可以各自獨(dú)立改變。
- Subject在發(fā)送廣播通知的時(shí)候,無須指定具體的Observer,Observer可以自己決定是否要訂閱Subject的通知。
- 遵守大部分GRASP原則和常用設(shè)計(jì)原則,高內(nèi)聚、低耦合。
observer模式的缺點(diǎn)
- 松耦合導(dǎo)致代碼關(guān)系不明顯;
- 如果一個(gè)Subject被大量Observer訂閱的話,在廣播通知的時(shí)候可能會(huì)有效率問題。(畢竟只是簡(jiǎn)單的遍歷);
- 如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴的話,觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用,可能導(dǎo)致系統(tǒng)崩潰。
實(shí)現(xiàn)
1. 創(chuàng)建被觀察者類,繼承自java.util.Observable類;
public class HousePriceObservable extends Observable {
private int price=0;
public int getPrice() {
return price;
}
public void setPrice(int i) {
price = i;
setChanged();
notifyObservers();
}
}
HousePriceObservable是被觀察者,當(dāng)它的數(shù)據(jù)發(fā)生變化,調(diào)用
setChanged();
notifyObservers();
通知它的觀察者。
2. 創(chuàng)建觀察者類,它實(shí)現(xiàn)java.util.Observer接口;
要實(shí)現(xiàn)Observer接口的唯一方法update
public class HousePriceObserver implements Observer {
public void update(Observable o,Object arg) {
HousePriceObservable m = (HousePriceObservable) o;
System.out.println("HousePrice has changed to "+ m.getPrice());
}
}
HousePriceObserver是觀察者,當(dāng)他的被觀察者HousePriceObservable 執(zhí)行了notifyObservers()方法后,它會(huì)調(diào)用update()方法。
3.對(duì)于被觀察者需要調(diào)用addObserver()方法,添加它的觀察者列表。
void addObserver(Observer o)
測(cè)試代碼
HousePriceObservable mHousePriceObservable = new HousePriceObservable();
HousePriceObserver mHousePriceObserver = new HousePriceObserver();
mHousePriceObservable.addObserver(mHousePriceObserver);
mHousePriceObservable.setPrice(1);
mHousePriceObservable.setPrice(2);
mHousePriceObservable.setPrice(3);