下面介绍在学习《深入浅出设计模式》中的第二个设计模式:观察者模式
先定义一下观察者模式:观察者模式定义了对象之间的一对多依赖,这样当一个对象改变状态时,它的所有对象都会收到依赖并且自动更新。
具体的示例请看下图:
观察者模式在实际应用中被使用的相当广泛。这种设计模式体现了主体对象与观察者对象之间的松耦合机制,主体对象有一个状态,每当状态改变时,它会依次去通知在它的队列中注册过的观察者。但实际上主体对象并不知道具体的观察者是什么,它只是调用一个观察者留下来的接口。这种设计带来的好处是,避免了很多个对象同时去访问同一片数据,这实际上是一种推送的方式,无论是要增加新的观察者或者是要减少观察者,我们只需要的是注册和注销而已,并不需要去改动主体对象的核心代码,具有极大的灵活性。
这里体现了一个设计原则:
为了交互对象之间的松耦合而努力。
书中主要举了一个气象监测应用的例子。应用观察者模式可以很好的解决这个问题。我们先来看一下设计好的类图。
最终用python实现的代码如下:
'''
The second Design Pattern:
Observer Pattern
KeyNote:
'''
class Observer:
def update(self, temp, humidity, pressure):
return
def display(self):
return
class Subject:
def registerObserver(self, observer):
return
def removeObserver(self, observer):
return
def notifyObservers(self):
return
class WeatherData(Subject):
def __init__(self):
self.observers = []
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
return
def registerObserver(self, observer):
self.observers.append(observer)
return
def removeObserver(self, observer):
self.observers.remove(observer)
return
def getTemperature(self):
return self.temperature
def getHumidity(self):
return self.humidity
def getPressure(self):
return self.pressure
def measurementsChanged(self):
self.notifyObservers()
return
def setMesurement(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.measurementsChanged()
return
def notifyObservers(self):
for item in self.observers:
item.update(self.temperature, self.humidity, self.pressure)
return
class CurrentConditionDisplay(Observer):
def __init__(self, weatherData):
self.weatherData = weatherData
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
weatherData.registerObserver(self)
return
def update(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.display()
return
def display(self):
print 'temprature = %f, humidity = %f.' % \
(self.temperature, self.humidity)
return
class StatiticDisplay(Observer):
def __init__(self, weatherData):
self.weatherData = weatherData
self.temperature = 0.0
self.humidity = 0.0
self.pressure = 0.0
weatherData.registerObserver(self)
return
def update(self, temp, humidity, pressure):
self.temperature = temp
self.humidity = humidity
self.pressure = pressure
self.display()
return
def display(self):
print 'Statictic: t = %f, h = %f, pressure = %f.' % \
(self.temperature, self.humidity, self.pressure)
return
weather = WeatherData()
display = CurrentConditionDisplay(weather)
weather.setMesurement(2.0, 3.0, 4.0)
display = StatiticDisplay(weather)
weather.setMesurement(3.0, 4.0, 5.0)