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

来源:互联网 发布:新网域名转到阿里云 编辑:程序博客网 时间:2024/05/24 06:30

观察者模式(Observer):

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

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

原则:

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

案例:

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

代码:

#!/usr/bin/pythonclass Subject:    def register(self, observer):        pass    def deregister(self, observer):        pass    def notify_observers(self):        passclass Observer:    def update(self, temperature, humidity, pressure):        passclass DisplayElement:    def display(self):        passclass 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=100Average Data: temperature=18, humidity=70, pressure=100Current Data: temperature=20, humidity=70, pressure=120Average Data: temperature=19, humidity=70, pressure=110Current Data: temperature=22, humidity=70, pressure=80Average Data: temperature=20, humidity=70, pressure=100Current Data: temperature=24, humidity=70, pressure=40Average Data: temperature=21, humidity=70, pressure=85Current Data: temperature=30, humidity=70, pressure=100Current Data: temperature=40, humidity=70, pressure=120

参考:

《Head First 设计模式》

原创粉丝点击