下面介紹在學習《深入淺出設計模式》中的第二個設計模式:觀察者模式
先定義一下觀察者模式:觀察者模式定義了對象之間的一對多依賴,這樣當一個對象改變狀態時,它的所有對象都會收到依賴並且自動更新。
具體的樣本請看下圖:
觀察者模式在實際應用中被使用的相當廣泛。這種設計模式體現了主體對象與觀察者對象之間的松耦合機制,主體對象有一個狀態,每當狀態改變時,它會依次去通知在它的隊列中註冊過的觀察者。但實際上主體對象並不知道具體的觀察者是什麼,它只是調用一個觀察者留下來的介面。這種設計帶來的好處是,避免了很多個對象同時去訪問同一片資料,這實際上是一種推送的方式,無論是要增加新的觀察者或者是要減少觀察者,我們只需要的是註冊和登出而已,並不需要去改動主體對象的核心代碼,具有極大的靈活性。
這裡體現了一個設計原則:
為了互動對象之間的松耦合而努力。
書中主要舉了一個氣象監測應用的例子。應用觀察者模式可以很好的解決這個問題。我們先來看一下設計好的類圖。
最終用python實現的代碼如下:
''' The second Design Pattern: Observer PatternKeyNote: '''class Observer: def update(self, temp, humidity, pressure): return def display(self): returnclass Subject: def registerObserver(self, observer): return def removeObserver(self, observer): return def notifyObservers(self): returnclass WeatherData(Subject): def __init__(self): self.observers = [] self.temperature = 0.0 self.humidity = 0.0 self.pressure = 0.0 return def registerObserver(self, observer): self.observers.append(observer) return def removeObserver(self, observer): self.observers.remove(observer) return def getTemperature(self): return self.temperature def getHumidity(self): return self.humidity def getPressure(self): return self.pressure def measurementsChanged(self): self.notifyObservers() return def setMesurement(self, temp, humidity, pressure): self.temperature = temp self.humidity = humidity self.pressure = pressure self.measurementsChanged() return def notifyObservers(self): for item in self.observers: item.update(self.temperature, self.humidity, self.pressure) returnclass CurrentConditionDisplay(Observer): def __init__(self, weatherData): self.weatherData = weatherData self.temperature = 0.0 self.humidity = 0.0 self.pressure = 0.0 weatherData.registerObserver(self) return def update(self, temp, humidity, pressure): self.temperature = temp self.humidity = humidity self.pressure = pressure self.display() return def display(self): print 'temprature = %f, humidity = %f.' % \ (self.temperature, self.humidity) returnclass StatiticDisplay(Observer): def __init__(self, weatherData): self.weatherData = weatherData self.temperature = 0.0 self.humidity = 0.0 self.pressure = 0.0 weatherData.registerObserver(self) return def update(self, temp, humidity, pressure): self.temperature = temp self.humidity = humidity self.pressure = pressure self.display() return def display(self): print 'Statictic: t = %f, h = %f, pressure = %f.' % \ (self.temperature, self.humidity, self.pressure) return weather = WeatherData()display = CurrentConditionDisplay(weather)weather.setMesurement(2.0, 3.0, 4.0)display = StatiticDisplay(weather)weather.setMesurement(3.0, 4.0, 5.0)