必須做作業三:氣象項目中觀察者模式解析
阿新 • • 發佈:2018-10-23
date edi splay 取數據 app 通知 mov pen con
觀察者模式
定義對象間的一種一對多依賴關系,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知並被自動更新。觀察者模式又叫做發布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
觀察者模式是一種對象行為型模式。
目的
建立一種對象與對象之間的依賴關系,一個對象發生改變時將自動通知其他對象,其他對象將相應做出反應。在此,發生改變的對象稱為觀察目標,而被通知的對象稱為觀察者,一個觀察目標可以對應多個觀察者,而且這些觀察者之間沒有相互聯系,可以根據需要增加和刪除觀察者,使得系統更易於擴展,這就是觀察者模式的模式動機。
結構
觀察者模式包含如下角色:
Subject: 目標
ConcreteSubject: 具體目標
Observer: 觀察者
ConcreteObserver: 具體觀察者
來源
示例
我們以Github上的一個觀察者模式的項目為例,見這裏 。
該項目是一個氣象更新顯示系統,在氣象站數據更新後,能夠自動更新顯示面板的信息。
源碼分析
觀察者觀察的對象
稱為可觀察對象,需要實現具體的註冊和刪除管理者方法。
class AbstractObservable(object): def register(self): raise NotImplementedError( ‘register is a abstract method which must be implemente‘) def remove(self): raise NotImplementedError( ‘remove is a abstract method which must be implemente‘)
觀察者抽象類
讓可觀察對象通知觀察者
class AbstractDisplay(object): def update(self): raise NotImplementedError( ‘update is a abstract method which must be implemente‘) def display(self): raise NotImplementedError( ‘display is a abstract method which must be implemente‘)
Subject
用於管理多個事件的通知,管理多個可觀察對象
class Subject(object):
def __init__(self, subject):
self.subject = subject
self._observers = []
def register(self, ob):
self._observers.append(ob)
def remove(self, ob):
self._observers.remove(ob)
def notify(self, data=None):
for ob in self._observers:
ob.update(data)
WeatherData
用於管理氣象數據
https://github.com/zhengxiaowai/design-patterns/blob/master/behavioral/observer.py#L41
class WeatherData(AbstractObservable):
def __init__(self, *namespaces):
self._nss = {}
self._clock = None
self._temperature = None
self._humidity = None
self._oxygen = None
for ns in namespaces:
self._nss[ns] = Subject(ns)
......
......
OverviewDisplay
總覽顯示面板,獲取當前數據並顯示
class OverviewDisplay(AbstractDisplay):
def __init__(self):
self._data = {}
def update(self, data):
self._data = data
self.display()
def display(self):
print(u‘總覽顯示面板:‘)
for k, v in self._data.items():
print(k + ‘: ‘ + str(v))
main 函數
借助觀察者模式,氣象數據更新後,可以通過可觀察對象管理者的notify接口,通知觀察者更新數據。
if __name__ == ‘__main__‘:
import time
# 生成一個可觀察對象,支持(‘all‘, ‘temperature‘, ‘humidity‘, ‘oxygen‘)的數據通知
wd = WeatherData(‘all‘, ‘temperature‘, ‘humidity‘, ‘oxygen‘)
# 兩個觀察者對象
od = OverviewDisplay()
td = TemperatureDisplay()
# 註冊到可觀察對象中,能獲取數據更新
wd.register(‘all‘, od)
wd.register(‘temperature‘, td)
# 更新數據,可觀察對象將會自動更新數據
wd.set_measurement({
‘clock‘: time.strftime("%Y-%m-%d %X", time.localtime()),
‘temperature‘: 20,
‘humidity‘: 60,
‘oxygen‘: 10
})
# 一秒後再次更新數據
time.sleep(1)
print(‘\n‘)
wd.set_measurement({
‘clock‘: time.strftime("%Y-%m-%d %X", time.localtime()),
‘temperature‘: 21,
‘humidity‘: 58,
‘oxygen‘: 7
})
優點
當數據更新後,可以自動通知觀察者
目標擴展性更強
實現了目標與觀察者之間的抽象耦合
實現了廣播通信
必須做作業三:氣象項目中觀察者模式解析