結(jié)構(gòu)型設計模式
簡要定義
定義了對象之間的一對多依賴,當一個對象改變狀態(tài)時,它的所有依賴者都會受到通知并自動更新.
類圖
observer.png
要點
- 觀察者模式定義了對象之間的一對多的關(guān)系.
- 被觀察者用一個共同的接口來更新觀察者.
- 觀察者與被觀察者松耦合,被觀察者不知道觀察者的細節(jié)
- 有多個觀察者時,不可以依賴特定的通知次序(通知次序不定)
實現(xiàn)
以氣象站為例
public interface Subject {
public void registerObserver(Observer O);
public void removeBoserver(Observer O);
public void notifyObservers(); //當被觀察者狀態(tài)改變時,這個方法會被調(diào)用來通知所有的觀察者.
}
public interface Observer {
public void update(float temp,float humidity,float pressure);
// 當氣象觀測值改變時,被觀察者把狀態(tài)值當做這個函數(shù)的參數(shù),傳給觀察者.
}
public class WeatherData implements Subject {
private ArrayList observers; //記錄觀察者
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeBoserver(Observer o){
int i =observers.indexOf(o);
if(i>0){
observers.remove(i);
}
}
public void notifyObservers() {
for(int i=0;i<observers.size;i++) {
Observers observer= (Observer) observers.get(i);
observer.update(temperature,humidity,pressure);
}
}
}
public class CurrentConditions implements Observer{
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData; //被觀察者對象
//在構(gòu)造器中實現(xiàn)觀察者登記
public CurrentConditions(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
}
}
觀察者模式弊端
- 如果觀察者過多的話趁矾,導致被觀察者中的列表太大洽腺,會有性能上的問題人弓。所以要視情況而定再使用,當然也可以結(jié)合線程池等來優(yōu)化。
- 如果在被觀察者之間有循環(huán)依賴的話,被觀察者會觸發(fā)它們之間進行循環(huán)調(diào)用,導致系統(tǒng)崩潰宴凉。在使用觀察者模式是要特別注意這一點。
應用場景
- 當需要將一個對象狀態(tài)的改變傳遞給其他對象,但不清楚有多少個具體待通知對象時.
- 通知和待通知對象都是易變體,需要封裝變化時.
具體游戲場景應用
- 事件分發(fā)管理器表悬。當用戶進行觸摸、按鍵等輸入后丧靡,輸入管理類將事件分發(fā)給添加了事件監(jiān)聽的對象蟆沫。
- 游戲業(yè)務邏輯與游戲控制器。當游戲業(yè)務邏輯改變了自身狀態(tài)后温治,將該變化通知給添加了監(jiān)聽的控制器饭庞。