以上是API手冊里觀察者的UML圖,(本文主要討論自己實現觀察者模式,JDK內置的就自己百度下吧)從上圖中我們可以看出一共需要兩個接口,兩個具體的實現類,分別是觀察者接口,觀察者實現類,被觀察者接口,被觀察者實現類,并且被觀察者中會有多個觀察者,因此我們想到的是用一個集合框架來儲存觀察者(例如List),也就是使用組合啦。

下面的東西通過具體代碼來解析給大家聽。
場景是有一條變色龍,然后有一堆人在猥瑣地注視著它(好可憐哇。。。),當變色龍變色的時候,所有人要將新的顏色記錄下來。

首先是觀察者接口

package org.black.observer;
public interface Observer {
 
public void update(Object observable);
}
代碼很簡單,update方法做的就是當變色龍變色的時候調用的方法,并且因為要知道變色龍的顏色,所以需要傳遞一個參數,讀者會問,那直接傳遞String color就可以了哇,寫成對象的目的是為了防止需求的改變,萬一以后變色龍有沒有吐舌頭都要你記錄的時候,你就可以不需要在此方法多加參數了。

接下來是觀察者的實現類。
package org.black.observer;
import org.black.observable.Bsl;

public class Person implements Observer {

    
private String name;

    
public Person(String name){
    
this.name = name;
    }


    
public void update(Object observable) {
    Bsl bsl 
= (Bsl)observable;
    System.out.println(name
+"記錄了變色龍的顏色為:"+bsl.getColor());
    }


}


這里代碼不做多解析,強轉的那個地方也是為了應變需求改變,萬一以后不僅僅要記錄變色龍,還要記錄鸚鵡什么的,那接口的代碼也就不需要改變了。

然后是被觀察者接口

package org.black.observable;
import org.black.observer.Observer;

public interface Observable {

    
public void addObserver(Observer observer);

    
public void removeObserver(Observer observer);

    
public void notifyAllObserver();
}

 

這里前兩個方法為的就是添加觀察者和除去觀察者唄,通知方法就是當狀態改變的時候,要告知所有的觀察者,這里可能有點懵,看了實現類就很容易懂了。

下面是被觀察者實現類

 

package org.black.observable;
import java.util.ArrayList;
import java.util.List;
import org.black.observer.Observer;
public class Bsl implements Observable {

private String color = "綠色";
private List<Observer> observerList = new ArrayList<Observer>();

public void addObserver(Observer observer) {
observerList.add(observer);
}

public void removeObserver(Observer observer) {
observerList.remove(observer);
}


public void notifyAllObserver() {
for(Observer observer : observerList){
   observer.update(
this);
}

   
}

public void changeColor(String color){
this.color = color;
System.out.println(
"變色龍將顏色變為:"+color);
notifyAllObserver();
}


public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

}


在這里,color就是被觀察者的狀態啦,當這個狀態改變的時候就必須告訴所有的觀察者,所以changeColor里面需要調用notifyAllObserver
下面是主函數

package org.black.test;
import org.black.observable.Bsl;
import org.black.observer.Observer;
import org.black.observer.Person;
public class TestObserver {
/**
@param args
*/

public static void main(String[] args) {
Bsl bsl 
= new Bsl();

Observer p1 
= new Person("hjq");
Observer p2 
= new Person("zz");

bsl.addObserver(p1);

bsl.addObserver(p2);

bsl.changeColor(
"黃色");

bsl.removeObserver(p2);

bsl.addObserver(
new Observer(){
   
public void update(Object observable) {
    Bsl bsl 
= (Bsl)observable;
    System.out.println(
"無名氏記錄了變色龍的顏色為:"+bsl.getColor());
   }

   
}
);

bsl.changeColor(
"紅色");

}

}

 

匿名類的寫法相信大家一定非常熟悉了,很像SWING里面的addListener,很方便,遺憾的是,不能知道名字,也沒辦法remove了。

結果是


變色龍將顏色變為:黃色
hjq記錄了變色龍的顏色為:黃色
zz記錄了變色龍的顏色為:黃色
變色龍將顏色變為:紅色
hjq記錄了變色龍的顏色為:紅色
無名氏記錄了變色龍的顏色為:紅色

大家多多支持。。以后會推出更多的設計模式的代碼,力求簡單生動,易于理解。。