zoukankan      html  css  js  c++  java
  • Python 设计模式 观察者模式

      观察者模式 :定义了内部的对象之间是1:n的关系,当一个对象的状态发生了变化,与这个对象相关联的数据都会同时发生改变。

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

      类图:其中的ConcreteSubject就是相关的报纸。

    案例:现在要实现一个气象站,观测四个数据,有气压,温度,湿度,可见度,但是有多个地点的公告板,需要使用到其中的数据。当其中的一个数据发生改变,其他的公告板,会马上得到更新。

    基本实现如下:

    定义基本模型: Subject,Obverser

    Model_Interface
    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  

    其中具体主题有WeatherData, 具体的订阅者有AverageDisplay,CurrentDisplay

    订阅者
     1 class WeatherData(Subject):  
     2     def __init__(self):  
     3         self.observers = []  
     4   
     5     def register(self, observer):  
     6         if observer not in self.observers:  
     7             self.observers.append(observer)  
     8   
     9     def deregister(self, observer):  
    10         if observer in self.observers:  
    11             self.observers.remove(observer)  
    12   
    13     def notify_observers(self):  
    14         for o in self.observers:  
    15             o.update(self.temperature, self.humidity, self.pressure)  
    16   
    17     def data_changed(self):  
    18         self.notify_observers()  
    19   
    20     def set_data(self, temperature, humidity, pressure):  
    21         self.temperature = temperature  
    22         self.humidity = humidity  
    23         self.pressure = pressure  
    24         self.data_changed()  
    25   
    26   
    27 class CurrentDisplay(Observer, DisplayElement):  
    28     def __init__(self, weather_data=None):  
    29         self.weather_data = weather_data  
    30         self.weather_data.register(self)  
    31   
    32     def update(self, temperature, humidity, pressure):  
    33         self.temperature = temperature   
    34         self.humidity = humidity  
    35         self.pressure = pressure  
    36         self.display()  
    37   
    38     def display(self):  
    39         print "Current Data: temperature=%s, humidity=%s, pressure=%s" % \  
    40             (self.temperature, self.humidity, self.pressure)  
    41   
    42 class AverageDisplay(Observer, DisplayElement):  
    43     def __init__(self, weather_data=None):  
    44         self.temperature = []  
    45         self.humidity = []  
    46         self.pressure = []  
    47         self.weather_data = weather_data  
    48         self.weather_data.register(self)  
    49   
    50     def update(self, temperature, humidity, pressure):  
    51         self.temperature.append(temperature)  
    52         self.humidity.append(humidity)  
    53         self.pressure.append(pressure)  
    54         self.display()  
    55   
    56     def average(self,lst):  
    57         n = 0  
    58         for x in lst:  
    59             n += x  
    60         return n/len(lst)  
    61   
    62     def display(self):  
    63         print "Average Data: temperature=%s, humidity=%s, pressure=%s" % \  
    64             (self.average(self.temperature), \  
    65             self.average(self.humidity), \  
    66             self.average(self.pressure))  

    测试

    View Code
     1 if __name__ == '__main__':  
     2     weather_data = WeatherData()  
     3   
     4     current = CurrentDisplay(weather_data)  
     5     average = AverageDisplay(weather_data)  
     6   
     7     weather_data.set_data(18,70,100); print  
     8     weather_data.set_data(20,70,120); print  
     9     weather_data.set_data(22,70,80); print  
    10     weather_data.set_data(24,70,40); print  
    11   
    12     weather_data.deregister(average)  
    13     weather_data.set_data(30,70,100); print  
    14     weather_data.set_data(40,70,120); print 

    OK ,Game Over

  • 相关阅读:
    html分页自适应居中;css设置分页自适应居中
    jQuery如何给DOM添加ID
    jquery如何获取div下ul的某个li
    js正则验证数字的方法
    css改变input输入框placeholder值颜色
    js校验表单后提交表单的三种方法总结
    Thinkcmf子栏目获取父级栏目所有子栏目列表
    Thinkcmf截取内容长度
    thinkcmf2.2 火狐浏览器图片上传以及谷歌图片上传打开稍慢
    c语言结构体中的冒号的用法
  • 原文地址:https://www.cnblogs.com/jerryxing/p/2873526.html
Copyright © 2011-2022 走看看