设计模式:观察者模式(Python)

观察者模式(Observer):

定义了对象间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

类似报纸订阅,当订阅报纸后,一有更新就会自动收到,除非退订;这里我们将出版者称为“主题”(Subject),订阅者成为“观察者”(Observer)。

原则:

为交互对象之间的松耦合而努力

案例:

现在要实现一个气象站,观测三个数据:温度,湿度和气压;气象站有两个布告板:分别显示当前最新值和平均值;当气象数据更新后,气象站要能自动跟新所有布告板。

代码:

#!/usr/bin/python

class Subject:
    def register(self, observer):
        pass

    def deregister(self, observer):
        pass

    def notify_observers(self):
        pass

class Observer:
    def update(self, temperature, humidity, pressure):
        pass

class DisplayElement:
    def display(self):
        pass



class WeatherData(Subject):
    def __init__(self):
        self.observers = []

    def register(self, observer):
        if observer not in self.observers:
            self.observers.append(observer)

    def deregister(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)

    def notify_observers(self):
        for o in self.observers:
            o.update(self.temperature, self.humidity, self.pressure)

    def data_changed(self):
        self.notify_observers()

    def set_data(self, temperature, humidity, pressure):
        self.temperature = temperature
        self.humidity = humidity
        self.pressure = pressure
        self.data_changed()


class CurrentDisplay(Observer, DisplayElement):
    def __init__(self, weather_data=None):
        self.weather_data = weather_data
        self.weather_data.register(self)

    def update(self, temperature, humidity, pressure):
        self.temperature = temperature 
        self.humidity = humidity
        self.pressure = pressure
        self.display()

    def display(self):
        print "Current Data: temperature=%s, humidity=%s, pressure=%s" % \
            (self.temperature, self.humidity, self.pressure)

class AverageDisplay(Observer, DisplayElement):
    def __init__(self, weather_data=None):
        self.temperature = []
        self.humidity = []
        self.pressure = []
        self.weather_data = weather_data
        self.weather_data.register(self)

    def update(self, temperature, humidity, pressure):
        self.temperature.append(temperature)
        self.humidity.append(humidity)
        self.pressure.append(pressure)
        self.display()

    def average(self,lst):
        n = 0
        for x in lst:
            n += x
        return n/len(lst)

    def display(self):
        print "Average Data: temperature=%s, humidity=%s, pressure=%s" % \
            (self.average(self.temperature), \
            self.average(self.humidity), \
            self.average(self.pressure))


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

    current = CurrentDisplay(weather_data)
    average = AverageDisplay(weather_data)

    weather_data.set_data(18,70,100); print
    weather_data.set_data(20,70,120); print
    weather_data.set_data(22,70,80); print
    weather_data.set_data(24,70,40); print

    weather_data.deregister(average)
    weather_data.set_data(30,70,100); print
    weather_data.set_data(40,70,120); print

输出:

Current Data: temperature=18, humidity=70, pressure=100
Average Data: temperature=18, humidity=70, pressure=100

Current Data: temperature=20, humidity=70, pressure=120
Average Data: temperature=19, humidity=70, pressure=110

Current Data: temperature=22, humidity=70, pressure=80
Average Data: temperature=20, humidity=70, pressure=100

Current Data: temperature=24, humidity=70, pressure=40
Average Data: temperature=21, humidity=70, pressure=85

Current Data: temperature=30, humidity=70, pressure=100

Current Data: temperature=40, humidity=70, pressure=120

参考:

《Head First 设计模式》

你可能感兴趣的:(设计模式,python,Class,出版)