《 Head First 》學習筆記:觀察者模式 (python實現)

病殃殃的仍是來記錄一下學習筆記,否則的話過幾天可能就忘了,白學了。 java

observer mode 在java 用得不少,咱也試一下用python來實現,因爲python沒有接口,就只能繼承一個類來用用了。 python

先擼一下代碼: redis

ubuntu@yee:/tmp/observer$ vim subject.py

#!/usr/bin/python 
#-*-  coding:utf8  -*- 

class Subject(object): //主題發佈中心
    def registerObserver(self,observer): //註冊觀察者
        pass

    def removeObserver(self,observer):  //刪除觀察者
        pass

    def notifyObservers(self): //通知中心
        pass


class Observer(object): //觀察者
    def update(self,temp,humidity,pressure):
        pass

class DisplayElement(object): //全部的觀察都是繼承於它,=。= 
    def display(self):
        pass

ubuntu@yee:/tmp/observer$ vim display.py
//這是佈告板

#!/usr/bin/python  
#-*- coding:utf8 -*-

from subject import Observer,DisplayElement
from weather import WeatherData

class CurrentConditionsDisplay(Observer,DisplayElement):
    def __init__(self,weatherData):
        super(CurrentConditionsDisplay,self).__init__()
        self.weatherData = weatherData
        self.weatherData.registerObserver(self) //向發佈中心註冊本身

    def update(self,temp,humidity,pressure): //獲得發佈中心傳送來的消息以後更新數據 
        self.temp = temp
        self.humidity = humidity
        self.pressure = pressure
        self.display()

    def display(self):
        print("Current conditions:" + str(self.temp) + 'F degrees and ' + str(self.humidity) + "% humidity")


ubuntu@yee:/tmp/observer$ vim weather.py
#!/usr/bin/python 
#-*-  coding:utf8  -*- 

from   subject  import  Subject,Observer,DisplayElement

class WeatherData(Subject):
    observers = list() //存儲觀察者列表 

    def __init__(self):
        super(WeatherData,self).__init__()
        self.observers = list()

    def registerObserver(self,observer):
        self.observers.append(observer)

    def removeObserver(self,observer):
        if self.observers.index(observer) >=  0:
            self.observers.remove(observer)

    def notifyObservers(self):
        for o in self.observers :
            o.update(self.temp,self.humidity,self.pressure)

    def measurementsChanged(self):
        self.notifyObservers()

    def setMeasurements(self,temp,humidity,pressure):
        self.temp = temp
        self.humidity = humidity
        self.pressure = pressure
        self.measurementsChanged()

ubuntu@yee:/tmp/observer$ vim main.py
#!/usr/bin/python 
#-*-  coding:utf8 -*- 

from subject import Subject ,Observer,DisplayElement
from weather import WeatherData
from display import CurrentConditionsDisplay


if __name__ == '__main__' :
    weather  = WeatherData()

    currentDisplay = CurrentConditionsDisplay(weather)

    weather.setMeasurements(80,65,20)
    weather.setMeasurements(99,88,220)
顯示效果 :
ubuntu@yee:/tmp/observer$ python main.py 
Current conditions:80F degrees and 65% humidity
Current conditions:99F degrees and 88% humidity
大體看一下上面的代碼,若是看懂了,其實也就理解了,邏輯很簡單:

一箇中心的消息發佈者,容許會員註冊,一旦有新消息,發佈中心會當即通知全部會員並傳送新消息過去。 ubuntu

舉個具體的應用例子,用過redis 的人,應該會知道,redis 有個sub/pub 的機制,效果圖以下: vim

左圖中先用「subscribe room1 room2 」 訂閱了兩個聊天室,右圖中 聊天室 room1 發佈了一條消息,左圖中的room1 立刻就收到了。 app

我想這就是觀察者模式(訂閱模式)的一個現實中的例子。 學習

相關文章
相關標籤/搜索