下面介绍在学习《深入浅出设计模式》中的第二个设计模式:观察者模式
先定义一下观察者模式:观察者模式定义了对象之间的一对多依赖,这样当一个对象改变状态时,它的所有对象都会收到依赖并且自动更新。
具体的示例请看下图:
观察者模式在实际应用中被使用的相当广泛。这种设计模式体现了主体对象与观察者对象之间的松耦合机制,主体对象有一个状态,每当状态改变时,它会依次去通知在它的队列中注册过的观察者。但实际上主体对象并不知道具体的观察者是什么,它只是调用一个观察者留下来的接口。这种设计带来的好处是,避免了很多个对象同时去访问同一片数据,这实际上是一种推送的方式,无论是要增加新的观察者或者是要减少观察者,我们只需要的是注册和注销而已,并不需要去改动主体对象的核心代码,具有极大的灵活性。
这里体现了一个设计原则:
为了交互对象之间的松耦合而努力。
书中主要举了一个气象监测应用的例子。应用观察者模式可以很好的解决这个问题。我们先来看一下设计好的类图。
最终用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)