觀察者模式在對象之間定義一對多的依賴關係,當主題對象發生變化時,依賴他的對象會收到通知並進行自動更新,觀察者模式有‘推’、‘拉’兩種模式,本人實現的是‘推’的方式,通過實現‘註冊——通知——撤銷註冊’三個過程實現觀察者模式。
由於第一次寫這麼多python代碼,出現2個錯誤,將足跡留下
1.在函數notifyObserver中調用update()和函數時一個參數少些了一個底線,導致調試不出來錯誤
由於是練習,update函數內沒有容錯處理,所以花了半個小時調試,另外這個錯誤編譯器也不給提示,僅僅顯示Traceback (most recent call last):
File "main.py", line 20, in <module>
2.好幾處類內部的成員前面忘記添加self,我想以後會慢慢習慣的。
模式的實現共分四個檔案來寫,由於python代碼基本上可以自解釋,這裡不再多說,以下是程式清單。
介面定義:interface.py
observer實現:observer.py
subject實現:weather_data.py 資料提供
main檔案:main.py
interface.py檔案清單
#-*- coding:utf-8 -*-
#subject interface
class ISubject():
def registerObserver(self, observer):
pass
def removeObserver(self, observer):
pass
def notifyObserver(self):
pass
#Observer interface
class IObserver():
def update(self, temp, humidity, pressure):
pass
#Display interface
class IDisplayElement():
def display(self):
pass
if '__main__' == __name__:
sbjt = ISubject()
sbjt.registerObserver(1)
sbjt.removeObserver(1)
sbjt.notifyObserver()
obsr = IObserver()
obsr.update(1,2,3)
observer.py檔案清單
#-*- coding:utf-8 -*-
from interface import IObserver, IDisplayElement
#inherit from IObserver, IDisplayElement
class CCurrentConditionDisplay(IObserver, IDisplayElement):
def __init__(self, temp = 0, humidity = 0, pressure = 0):
self.__temp = temp
self.__humidity = humidity
self.__pressure = pressure
def display(self):
print ('溫度', self.__temp)
print ('濕度', self.__humidity)
print ('壓力', self.__pressure)
def update(self, temp, humidity, pressure):
print ('update')
self.__temp = temp
self.__humidity = humidity
self.__pressure = pressure
self.display()
class CAddSomethingDisplay(IObserver, IDisplayElement):
def __init__(self, temp = 0, humidity = 0, pressure = 0):
self.__temp = temp
self.__humidity = humidity
self.__pressure = pressure
def display(self):
print ('溫度', self.__temp)
print ('濕度', self.__humidity)
print ('壓力', self.__pressure)
def update(self, temp, humidity, pressure):
#這裡是這個面板特殊的處理
#這裡只是簡單的加減數字類比
self.__temp = self.__temp + 1
self.__humidity = self.__humidity + 4
self.__pressure = self.__pressure + 7
self.display()
if '__main__' == __name__:
cc = CAddSomethingDisplay()
cc.update(1,2,3)
cc.display()
weather_data.py檔案清單
#-*- coding:utf-8 -*-
from interface import ISubject
from observer import *
#inherit form ISubject
class CWeatherData(ISubject):
def __init__(self, temp = 0, humidity = 0, pressure = 0):
self.observer_list = [] #用於記錄觀察者
self.__temp = temp #溫度 私人
self.__humidity = humidity #濕度
self.__pressure = pressure #氣壓
def registerObserver(self, observer):
self.observer_list.append(observer)
def removeObserver(self, observer):
self.observer_list.remove(observer)
def notifyObserver(self):
for obsvr in self.observer_list:
obsvr.update(self.__temp, self.__humidity, self.__pressure)
def measurementChanged(self):
self.notifyObserver()
def setMeasurements(self, temp, humidity, pressure):
self.__temp = temp
self.__humidity = humidity
self.__pressure = pressure
self.measurementChanged()
if '__main__' == __name__:
t = Test()
weather_data = CWeatherData()
weather_data.registerObserver(t)
weather_data.setMeasurements(1,5,2)
main.py檔案清單
#-- coding: utf-8 --
from weather_data import *
from observer import *
#main
if '__main__' == __name__:
weather_data = CWeatherData()
current = CCurrentConditionDisplay()
other_obsvr = CAddSomethingDisplay()
#添加對weather_data的觀察者
weather_data.registerObserver(current)
weather_data.registerObserver(other_obsvr)
#類比天氣變化
weather_data.setMeasurements(4, 1, 5)
#觀察者模式到此結束