废了这些年的程序员,必须掌握一些设计模式才算是真正称得上是“老司机”了。今天要介绍的就是其中之一——观察者模式。
1. 认识观察者模式
先说说这个模式的背景,这个模式主要是用于一对多的情况下,当一个对象发生改变时,所有其它对象都会受到通知并进行相应的操作。这样看起来观察者模式似乎很简单,但实现起来也有些讲究。
在观察者模式中,有两个角色需要我们关注下。一个是被观察者,我们叫它主题(Subject),即被观察的对象。它有一些状态需要在状态变化时通知其它对象加以处理。另一个是观察者(Observer),接收传入的信息并进行处理。当然,观察者也有多种形式,可以是类、函数、接口等。如果观察者仅仅只有一种,那就是傻观察者了。
对于被观察者和观察者,我们一定要用接口和抽象类进行定义:主题应该有一个添加观察者、删除观察者、以及通知所有观察者的方法。而观察者则需要有一个update方法来接收主题通知时传递过来的信息。这里带来一段伪代码。
```python
# 主题接口,记得从ABC继承
class Subject(metaclass=ABCMeta):
def registerObserver(self, observer): pass
def removeObserver(self, observer): pass
def notifyObserver(self): pass
# 观察者接口,从ABC继承
class Observer(metaclass=ABCMeta):
def update(self, temp, humidity, pressure): pass
```
这样我们可以定义观察者的接口和被观察者的接口了。接着我们就可以进行下一步——实现主题和观察者的类了。
2. 实现观察者模式
众所周知,Python中的面向对象编程是一种“急功近利”的做法。好在面向对象语言中多态的概念可以让这个模式的实现变得更加简单。现在假设我们要建立一个气象站,并提供给用户当前的温度、湿度和气压的变化信息。首先我们需要实现主题类WeatherData。下面是该类的简单实现:
```python
class WeatherData(Subject):
def __init__(self):
self.observers = []
self.temperature = None
self.humidity = None
self.pressure = None
def registerObserver(self, observer):
self.observers.append(observer)
def removeObserver(self, observer):
self.observers.remove(observer)
def notifyObserver(self):
for observer in self.observers:
observer.update(self.temperature, self.humidity, self.pressure)
def measurementsChanged(self):
self.notifyObserver()
def setMeasurements(self, temperature, humidity, pressure):
self.temperature = temperature
self.humidity = humidity
self.pressure = pressure
self.measurementsChanged()
```
实现了主题类之后,我们可以实现观察者类了。这里,我们以展示当前气象情况的类CurrentConditionsDisplay为例。下面是该类的代码:
```python
class CurrentConditionsDisplay(Observer):
def __init__(self, weather):
self.temperature = None
self.humidity = None
self.pressure = None
self.weather = weather
self.weather.registerObserver(self)
def update(self, temperature, humidity, pressure):
self.temperature = temperature
self.humidity = humidity
self.pressure = pressure
self.display()
def display(self):
print("Current conditions: %.1fF degrees and %.1f%% humidity" % (self.temperature, self.humidity))
```
这样我们就可以实现一个简单的观察者模式了!下面展示一下模型如何使用:
```python
weatherStation = WeatherData()
currentDisplay = CurrentConditionsDisplay(weatherStation)
weatherStation.setMeasurements(80, 65, 30.4)
weatherStation.setMeasurements(82, 70, 29.2)
weatherStation.setMeasurements(78, 90, 29.2)
```
3. 如何有亲和性地使用观察者模式
观察者模式最大的问题可能在于如果被观察者和观察者之间有太多的交互,那么这个模式可能会导致程序的难以维护。解决这个问题的一个办法是使用消息队列,将主题和所有的观察者分开,并且异步地传递消息。
现在让我们来举一个实际的例子,有一个购物车,里面有多个商品,用户可以随时删除这些商品。我们需要在商品被删除后通知相应的观察者。下面是一段示例的Python代码:
```python
from queue import Queue, Empty
class ShoppingCart:
def __init__(self):
self.items = []
self.observers = Queue()
def __add__(self, item):
self.items.append(item)
return self
def __iter__(self):
return iter(self.items)
def __delitem__(self, index):
del self.items[index]
self.notifyAll()
def registerObserver(self, observer):
self.observers.put(observer)
def removeObserver(self, observer):
try:
while True:
a = self.observers.get_nowait()
self.observers.put(a)
if a != observer:
self.observers.get_nowait()
except Empty:
return
def notifyAll(self):
while not self.observers.empty():
observer = self.observers.get_nowait()
observer() // 别忘了这是一个“傻观察者”!
```
上述代码中,我们将购物车和观察者进行了分离,并将通知消息异步发送给观察者。这样我们就大大简化了程序的实现,最终得到了一个适合维护的代码结构。
4. 结语:在实现观察者模式的过程中,我们需要考虑到两个关键部分:被观察者以及观察者的接口。同时,为了维护程序的可读性和可维护性,我们应该对它们分别定义一个接口或抽象类。如果这样做的话,就可以使我们的代码逻辑更加清晰,同时我们将更容易地对其进行测试。同时,我们还提供了针对观察者模式的优化技巧,通过使用消息队列等先进技术,可以更拥有更高的程序效率。总之,观察者模式提供了一种将代码进行结构化的方式,将带给你开发优秀产品的不错选择! www.0574web.net 宁波海美seo网络优化公司 是网页设计制作,网站优化,企业关键词排名,网络营销知识和开发爱好者的一站式目的地,提供丰富的信息、资源和工具来帮助用户创建令人惊叹的实用网站。 该平台致力于提供实用、相关和最新的内容,这使其成为初学者和经验丰富的专业人士的宝贵资源。
声明本文内容来自网络,若涉及侵权,请联系我们删除! 投稿需知:请以word形式发送至邮箱18067275213@163.com
站长大神好久不跟新了。认真拜读。
我觉得关键词的分析很浅。没有很大启发。感觉博主是有保留的分享,不过这个也可以理解。
很不错啊 , SEO还有这一点 呵呵
我也正挖着呢。
seo听起来是技术活,做到最后可能就是体力活了。每天都在为排名发愁。