觀察者模式體驗(yàn)就是一個(gè):
問(wèn)題:在做UI設(shè)計(jì)時(shí),遇到一個(gè)問(wèn)題,就是當(dāng)我點(diǎn)擊一個(gè)自定義對(duì)話框的復(fù)選框時(shí),自定義對(duì)話框的父界面必須做出相應(yīng)的改變,還有,自定義對(duì)話框是做成的組件,應(yīng)用于很多場(chǎng)合(有很多的界面用到此對(duì)話框);
//這是自定義的對(duì)話框,當(dāng)事件是checkbox時(shí),讓父界面做//出改變
Public class DialogBox implements ClickListener {
Public void onClick(event e){
}
}
//這是父界面,他彈出對(duì)話框
Public class ParentFrame extends ParentClass{
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
}
解決方案一:
我把父界面的父類(lèi)改變成自定義的父類(lèi),讓父界面繼承自定義的父類(lèi):
Public class DialogBox implements ClickListener{
Private Ojbect object = null ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
//當(dāng)事件是checkbox時(shí),強(qiáng)制轉(zhuǎn)換成Custom調(diào)用//update方法
((Custom)object).update();
}
}
}
//這是自定義類(lèi),它繼承了ParentClass,并抽象了個(gè)update方//法
Public abstact CustomClass extends ParentClass{
Public abstract void update() ;
}
Public class ParentFrame extends CustomClass {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
Public void update(){
//父界面的更新操作
}
}
這個(gè)解決方案確實(shí)解決的問(wèn)題,當(dāng)自定義對(duì)話框點(diǎn)擊checkbox時(shí),確實(shí)會(huì)使他的父界面發(fā)生改變,但他的缺點(diǎn)太大:必須繼承CustomClass才能具備這樣的功能,而且主要是因?yàn)樗淖兞死^承關(guān)系,在ParentFrame和ParentClass之間加了一層,這樣使耦合度加大了;而且每次都把自身的引用通過(guò)構(gòu)造傳過(guò)去(new DialogBox(this)),在dialogbox那邊還要強(qiáng)行轉(zhuǎn)換回來(lái),確實(shí)不是什么好辦法J
解決方案二:
//定義CustomListener接口
Public interface CustomListener (){
Public void update() ;
}
Public class DialogBox implements ClickListener{
Private Ojbect object = null ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
//當(dāng)事件是checkbox時(shí),強(qiáng)制轉(zhuǎn)換成Custom調(diào)用//update方法
((CustomListener)object).update();
}
}
}
//實(shí)現(xiàn)了CustomListener接口
Public class ParentFrame extends ParentClass implements CustomListener {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox(this) ;
}
Public void update(){
//父界面的更新操作
}
}
這個(gè)解決方案也是解決了問(wèn)題,尤其對(duì)第一解決方案而言,這個(gè)已經(jīng)不會(huì)打亂繼承關(guān)系,但是還沒(méi)有脫離第二個(gè)缺陷;
解決方案三:
//定義Listener接口
Public interface CustomListener(){
Public void update() ;
}
//定義event接口
Public interface CustomEvent(){
Public void addCustomListener(CustomListener listener) ;
Public void removeCustomListener(CustomListener listner) ;
Public void notify() ;
}
Public class DialogBox implements ClickListener, CustomEvent {
Private List listenerList = new ArrayList() ;
Private CheckBox checkbox = new CheckBox() ;
Public DialogBox(Ojbect object){
this.object = object ;
}
Public void onClick(event e){
If(e == checkbox){
notify() ;
}
}
//注冊(cè)一個(gè)觀察者
Public void addCustomListener(CustomListener listener) {
listenerList.add(listener) ;
}
//刪除一個(gè)觀察者
Public void removeCustomListener(CustomListener listner){
listenerList.remove(listener) ;
}
//調(diào)用所以注冊(cè)的觀察者
Public void notify() {
If(listenerList != null && !( listenerList.isEmpty)){
for(int I = 0 ; I < listenerList.size() ; I ++){
((CustomListener)listenerList.get(i)).update();
}
}
}
}
//實(shí)現(xiàn)了CustomListener接口
Public class ParentFrame extends ParentClass implements CustomListener {
Public void popDialogBox(){
DialogBox dialogbox = new DialogBox() ;
dialogbox. addCustomListener((CustomListener)this) ;
}
Public void update(){
//父界面的更新操作
}
}
第三中解決方案才是觀察者模式是應(yīng)用,這才是較為合理的方案;
觀察者模式應(yīng)用前提是:有一個(gè)對(duì)象出發(fā)事件時(shí),其他對(duì)象也發(fā)生改變;是個(gè)一對(duì)多的關(guān)系