你們好,咱們今天來了解一個新的設計模式——觀察者模式。web
觀察者模式的思路很簡單,它被普遍地用在各類數據監控上。不少時候咱們但願監聽某個數據的變化,但願一旦獲悉它的變化以後當即採起一些舉措。按照常規的操做,咱們須要開啓額外的線程來進行監聽。可是開啓線程一則很是麻煩,二則須要帶來額外的開銷,咱們今天介紹的觀察者模式就能夠在無需多餘開銷的基礎上完成這個功能。設計模式
在觀察者模式當中,整個運行流和常規的操做相反,咱們並非用一些程序去監聽數據的變化。相反而是當數據發生變化的時候,咱們去通知對應的監聽器數據產生了變化。好處咱們前面也說過了,能夠避免多餘的開銷。app
首先,咱們來實現兩個監聽器。也就是當數據發生變化以後會觸發這兩個監聽器。在這個設計模式當中,監聽器被命名爲viewer,這裏的觀察不是一種主動的觀察而是一種被動地接收通知。也許是起名的人想不出更好的名字來吧,其實我以爲應該叫作receiver更好。編輯器
class IncreaseViewer:
def __init__(self):
self.data = 0
def update(self, subject):
# 判斷是否增長
if subject.data > self.data:
print('Increased: Subject {} data increased to {}'.format(subject.name, subject.data))
self.data = subject.data
class DeclineViewer:
def __init__(self):
self.data = 0
def update(self, subject):
# 判斷是否減小
if subject.data < self.data:
print('Decreased: Subject %s data decreased to %d' % (subject.name, subject.data))
self.data = subject.data
觀察者的代碼應該很好理解,理解了觀察者類以後,咱們再來看看數據類。函數
數據的類其實也很簡單,咱們只須要設計一個功能,讓它能夠在數據發生賦值操做的時候去通知一下觀察者就能夠了。咱們都知道在Python當中,賦值操做是沒辦法直接感知的,可是類當中的成員發生變化的時候,咱們是能夠經過@property裝飾器來進行修飾的。優化
因此咱們就利用這一點來實現數據這個類,若是你們熟悉@property註解的話,也很是簡單。url
class Data(Subject):
def __init__(self, name=''):
Subject.__init__(self)
self.name = name
self._data = 0
@property
def data(self):
return self._data
@data.setter
def data(self, data):
self._data = data
# 關鍵
self.notify()
你們看到了data這個方法當中的self.notify了嗎?這個就是通知函數,因此就是當Data這個類當中的data成員發生變化的時候,咱們執行通知操做,去通知觀察者執行。spa
如今咱們觀察者實現好了,數據類也有了,剩下的就是把這二者連通起來了。咱們固然也能夠簡單粗暴地用代碼實現,可是比較好的作法是對數據和觀察者之間的聯繫作一個簡單的管理。由於可能不一樣的數據須要的觀察者不同,咱們並不能簡單粗暴地一律而論。線程
其實管理觀察者也不須要太複雜,只須要用面向對象的思路對list進行一個簡單的封裝便可。設計
class Subject:
def __init__(self):
self._observer = []
def attach(self, observer):
if observer not in self._observer:
self._observer.append(observer)
def detach(self, observer):
try:
self._observer.remove(observer)
except ValueError:
pass
def notify(self, modifier=None):
for observer in self._observer:
if modifier != observer:
observer.update(self)
attach表示關聯,也就是給數據關聯上觀察者,detach表示解除關聯,notify天然就是通知了。其實也就是用一個循環遍歷一下全部的觀察者,而後執行一下對應的update函數就能夠了。
這裏爲了簡化邏輯,咱們把Subject類作成了Data類的父類。這樣某種程度上至關於解耦了觀察者和數據,咱們之後不管是對哪部分邏輯進行修改或者是優化都不會影響另外兩方。整個代碼不過50行,能夠說是很是簡便了,不只是Python,對於其餘支出多態的語言來講,這個設計模式也是一樣適用的。
到這裏關於觀察者模式就介紹完了,今天的文章就到這裏。衷心祝願你們天天都有所收穫。若是還喜歡今天的內容的話,請來一個三連支持吧~(點贊、關注、轉發)