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

 

posted @ 2013-01-23 17:25  jerry_xing8  阅读(2106)  评论(0编辑  收藏  举报