JDKObserver設計模式之研究
目前設計模式的介紹性文章越來越多,但設計模式的研究性文章仍然比較欠缺,這著實讓人覺得有點遺憾。本文旨在拋磚引玉,具體分析一下java中jdk自帶的observer設計模式(下文如沒特別指出,observer設計模式就意指java中jdk自帶的observer設計模式)的實現。
1.Observer設計模式概要
Observer設計模式在GOF里屬于行為設計模式。JDK里提供的observer設計模式的實現由java.util.Observable類和java.util.Observer接口組成。從名字上可以清楚的看出兩者在Observer設計模式中分別扮演的角色:Observer是觀察者角色,Observable是被觀察目標(subject)角色。
Observable是一個封裝subject基本功能的類,比如注冊observer(attach功能),注銷observer(detatch功能)等。這些功能是任何一個扮演observerable角色的類都需要實現的,從這一點上來講,JDK里將這些通用功能專門封裝在一個類里,顯得合情合理。通常情況下,我們的類只要從Observerable類派生就可以稱為observerable角色類,使用非常簡單。
2.使用observer設計模式存在的困難
但我們不得不注意到,在項目實際開發當中,情況往往要復雜得多。java不支持多繼承特性在很多時候是阻礙我們使用observer設計模式的絆腳石。比如說,我們設計的一個類已經是某個類的派生類,在這種情況下同時想讓它扮演observerable角色將變得麻煩。如何實現“多繼承”的效果是擺在我們面前的一大難題。下面我們首先分析一下Observable類。
3.Observable類“觸發通知”的原理
Observable必須“有變化”才能觸發通知observer這一任務,這是它的本質體現。查看源碼便可知一二。Observerable部分源碼如下:
//……省略……
privatebooleanchanged=false;
//……省略……
publicvoidnotifyObservers(Objectarg){
//……省略……
Object[]arrLocal;
synchronized(this){
//……省略……
if(!changed)
return;
arrLocal=obs.toArray();
clearChanged();
}
//……省略……
protectedsynchronizedvoidsetChanged(){
changed=true;
}
protectedsynchronizedvoidclearChanged(){
changed=false;
}
正如粗的斜體標注部分所示,在notifyObservers(Objectarg)方法里if(!changed) return;語句告訴我們,若changed屬性值為false,將直接返回,根本不會觸發通知操作。并且我們注意到changed屬性被初始化為false,這將意味著如果我們不主動設置changed屬性為true,將不會有任何變化,也就是說根本起不到“通知”作用。因此,設置changed屬性的值是我們應用jdkobserver設計模式的關鍵所在。那么如何才能設置changed屬性呢?從源碼可以看出,唯一的入口是通過setChanged()。下面我們分析一下changed屬性及相關的方法setChanged()和clearChanged()。
1.Observer設計模式概要
Observer設計模式在GOF里屬于行為設計模式。JDK里提供的observer設計模式的實現由java.util.Observable類和java.util.Observer接口組成。從名字上可以清楚的看出兩者在Observer設計模式中分別扮演的角色:Observer是觀察者角色,Observable是被觀察目標(subject)角色。
Observable是一個封裝subject基本功能的類,比如注冊observer(attach功能),注銷observer(detatch功能)等。這些功能是任何一個扮演observerable角色的類都需要實現的,從這一點上來講,JDK里將這些通用功能專門封裝在一個類里,顯得合情合理。通常情況下,我們的類只要從Observerable類派生就可以稱為observerable角色類,使用非常簡單。
2.使用observer設計模式存在的困難
但我們不得不注意到,在項目實際開發當中,情況往往要復雜得多。java不支持多繼承特性在很多時候是阻礙我們使用observer設計模式的絆腳石。比如說,我們設計的一個類已經是某個類的派生類,在這種情況下同時想讓它扮演observerable角色將變得麻煩。如何實現“多繼承”的效果是擺在我們面前的一大難題。下面我們首先分析一下Observable類。
3.Observable類“觸發通知”的原理
Observable必須“有變化”才能觸發通知observer這一任務,這是它的本質體現。查看源碼便可知一二。Observerable部分源碼如下:
//……省略……
privatebooleanchanged=false;
//……省略……
publicvoidnotifyObservers(Objectarg){
//……省略……
Object[]arrLocal;
synchronized(this){
//……省略……
if(!changed)
return;
arrLocal=obs.toArray();
clearChanged();
}
//……省略……
protectedsynchronizedvoidsetChanged(){
changed=true;
}
protectedsynchronizedvoidclearChanged(){
changed=false;
}
正如粗的斜體標注部分所示,在notifyObservers(Objectarg)方法里if(!changed) return;語句告訴我們,若changed屬性值為false,將直接返回,根本不會觸發通知操作。并且我們注意到changed屬性被初始化為false,這將意味著如果我們不主動設置changed屬性為true,將不會有任何變化,也就是說根本起不到“通知”作用。因此,設置changed屬性的值是我們應用jdkobserver設計模式的關鍵所在。那么如何才能設置changed屬性呢?從源碼可以看出,唯一的入口是通過setChanged()。下面我們分析一下changed屬性及相關的方法setChanged()和clearChanged()。