8.观察者模式:思索与解读

打印 上一主题 下一主题

主题 1577|帖子 1577|积分 4731

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
原文地点:观察者模式:思索与解读  更多内容请关注:7.深入思索与解读计划模式
引言

开发软件时,体系的某些状态大概会发生变化,而你盼望这些变化能够主动通知到依赖它们的其他模块。你是否曾经遇到过,体系中某个对象发生了变化,但你不想让其他对象频仍地去询问这个变化,或者你不盼望每次变化时都手动通知这些对象?
假如可以有一种方式,当对象的状态发生变化时,所有依赖该对象的其他对象都能主动得到通知并做出相应,这样的计划是否会让你的体系更加松耦合且易于维护?
这正是观察者模式的目标。观察者模式通过界说一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知。你是否觉得,这样的模式能够减少体系中对象之间的耦合,使得体系更加灵活?
在这篇文章中,我们将通过一系列题目,渐渐引导你理解观察者模式的核心思想、应用场景以及如何实现它。
什么是观察者模式?

题目1:在软件计划中,假如有一个对象发生了变化,你通常如何通知其他依赖它的对象?

假设你有一个体系,其中有一个对象的状态变化会影响到其他多个对象。你是如何让这些依赖对象知道这个变化的?是否有一种方法,让这些对象在不询问的环境下,主动获取到最新的状态?
题目2:你是否曾经使用过“事件监听器”或“回调”机制?这些方法是否能够灵活地处置处罚对象之间的依赖关系?

事件监听器和回调机制在某些场景下黑白常有用的,但它们通常会带来强耦合。而观察者模式则能够更灵活地处置处罚一对多的依赖关系。你是否想过,是否有一种计划模式能够办理这种题目?
观察者模式正是办理这个题目标一种有效计划模式,它通过“观察者”来主动通知依赖对象,而不须要依赖对象主动查询。
观察者模式的核心概念

题目3:观察者模式通常由哪些脚色组成?每个脚色的职责是什么?

观察者模式包罗以下几个核心脚色:

  • 主题(Subject):被观察的对象,通常包罗一个状态,当它的状态发生变化时,会通知所有注册的观察者。
  • 观察者(Observer):依赖于主题的对象,当主题发生变化时,观察者会得到通知并进行相应的处置处罚。
  • 详细主题(ConcreteSubject):实现了主题接口,维护观察者列表,并在状态变化时通知它们。
  • 详细观察者(ConcreteObserver):实现了观察者接口,相应主题的变化。
你能理解这些脚色是如何相互协作,确保在主题变化时,观察者能够主动得到通知吗?
题目4:在观察者模式中,主题与观察者是如何解耦的?它们是如何通过某种机制进行通信的?

观察者模式的关键是,主题不须要知道详细有哪些观察者,它只须要维护一个观察者的列表,并在状态变化时通知所有的观察者。你能理解,这样的计划是如何让体系中的各个部分更加解耦的?
观察者模式的实现

让我们通过一个简单的例子来理解观察者模式的实现。假设你正在开发一个气候预报体系,体系中有多个展示气候信息的应用(例如,手机应用、网页应用等),当气候数据发生变化时,所有应用都应该被通知并更新显示的内容。
步调1:界说观察者接口

  1. from abc import ABC, abstractmethod
  2. # 观察者接口
  3. class Observer(ABC):
  4.     @abstractmethod
  5.     def update(self, temperature: float, humidity: float):
  6.         pass
复制代码
题目5:观察者接口(Observer)界说了哪些方法?为什么须要一个统一的接口来包管所有观察者的行为同等?

观察者接口界说了一个update()方法,所有观察者都必须实现这个方法。你是否理解,为什么这种方式能够确保所有观察者在状态变化时都能得到统一的通知,并进行相应的处置处罚?
步调2:界说主题接口

  1. class Subject(ABC):
  2.     @abstractmethod
  3.     def register_observer(self, observer: Observer):
  4.         pass
  5.     @abstractmethod
  6.     def remove_observer(self, observer: Observer):
  7.         pass
  8.     @abstractmethod
  9.     def notify_observers(self):
  10.         pass
复制代码
题目6:主题接口(Subject)须要提供哪些方法来管理观察者?它为什么须要register_observer()、remove_observer()和notify_observers()方法?

主题接口通过register_observer()、remove_observer()和notify_observers()来管理观察者列表。你是否理解,为什么这些方法是观察者模式的核心?它们如何资助主题管理观察者,并在状态变化时通知所有观察者?
步调3:界说详细主题类

  1. class WeatherStation(Subject):
  2.     def __init__(self):
  3.         self._observers = []
  4.         self._temperature = 0.0
  5.         self._humidity = 0.0
  6.     def register_observer(self, observer: Observer):
  7.         self._observers.append(observer)
  8.     def remove_observer(self, observer: Observer):
  9.         self._observers.remove(observer)
  10.     def notify_observers(self):
  11.         for observer in self._observers:
  12.             observer.update(self._temperature, self._humidity)
  13.     def set_weather_data(self, temperature: float, humidity: float):
  14.         self._temperature = temperature
  15.         self._humidity = humidity
  16.         self.notify_observers()  # 当天气数据变化时通知所有观察者
复制代码
题目7:详细主题类(WeatherStation)如何管理观察者,并在状态变化时通知它们?

WeatherStation类维护一个观察者列表,并通过notify_observers()方法通知所有观察者。你是否能理解,为什么我们通过set_weather_data()方法来触发状态变化,并通知所有的观察者?
步调4:界说详细观察者类

  1. class PhoneApp(Observer):
  2.     def update(self, temperature: float, humidity: float):
  3.         print(f"Phone App: Weather updated! Temperature: {temperature}°C, Humidity: {humidity}%")
  4. class WebApp(Observer):
  5.     def update(self, temperature: float, humidity: float):
  6.         print(f"Web App: Weather updated! Temperature: {temperature}°C, Humidity: {humidity}%")
复制代码
题目8:详细观察者类(如PhoneApp、WebApp)是如何相应主题的变化的?它们为什么须要实现update()方法?

详细观察者类实现了update()方法,并在该方法中处置处罚主题状态变化后的逻辑(如更新显示)。你是否理解,为什么观察者须要根据主题的变化来更新本身的状态,而这种更新是主动触发的?
步调5:客户端代码

  1. def main():
  2.     weather_station = WeatherStation()
  3.     phone_app = PhoneApp()
  4.     web_app = WebApp()
  5.     weather_station.register_observer(phone_app)
  6.     weather_station.register_observer(web_app)
  7.     weather_station.set_weather_data(25.5, 60)  # 模拟天气数据变化
  8.     weather_station.set_weather_data(30.0, 65)  # 再次模拟天气数据变化
  9. if __name__ == "__main__":
  10.     main()
复制代码
题目9:在客户端代码中,如何通过主题对象来注册观察者,并触发通知?当气候数据发生变化时,如何确保所有观察者都能接收到通知?

客户端通过register_observer()方法注册观察者对象,当气候数据变化时,WeatherStation通过调用notify_observers()通知所有注册的观察者。你是否理解,这种机制如何包管了在状态变化时,所有依赖对象(观察者)都能主动相应?
观察者模式的优缺点

题目10:观察者模式的优点是什么?它如何资助我们解耦体系中的不同模块?

观察者模式通过将主题与观察者解耦,制止了直接依赖关系,使得体系更加灵活和可扩展。你是否理解,这种计划如何资助你在不修改主题类的环境下,轻松增长新的观察者?同时,观察者也不须要知道主题类的详细实现。
题目11:观察者模式的缺点是什么?它在某些环境下是否会导致性能题目或过度通知?

虽然观察者模式非常灵活,但在某些环境下,当有大量观察者时,大概会导致性能题目。你是否以为,假如观察者数量过多,通知的服从大概成为瓶颈?或者,是否大概存在不须要的通知?
适用场景

题目12:你能想到哪些场景,观察者模式能够发挥作用?

观察者模式适用于以了局景:


  • 当多个对象依赖于某个对象的状态变化时。
  • 当你须要将事件驱动机制引入体系时。
你能想到其他场景吗?例如,用户界面的事件监听、股票市场的价格更新等,是否也可以使用观察者模式?
题目13:观察者模式是否适用于所有场景?在某些环境下,是否有更合适的计划模式?

观察者模式适用于须要多方监听和相应的场景,但假如对象之间的依赖较少,或者没有动态更新的需求,是否可以使用更简单的计划模式?
接下来,我们将通过详细的代码示例来加深理解观察者模式。
观察者模式深入解读

一、引言

观察者模式(Observer Pattern)是一种行为型计划模式,它界说了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者都会得到通知并主动更新。观察者模式通常用于事件处置处罚体系,比如用户界面、消息通知体系等。

二、简单理解:什么是观察者模式?

1. 什么是观察者模式?

观察者模式的核心思想是:当一个对象的状态发生改变时,所有依赖于它的对象都会主动得到通知并更新。这个模式常用于一种场景:当数据发生变化时,其他对象须要得到变化的通知并作出相应。
普通地讲,观察者模式就像是你订阅了一家新闻网站,每当该网站发布了新的新闻,你就会收到通知。你不须要主动去检查网站是否有新新闻,而是当新闻发生变化时,体系会主动通知你。
2. 观察者模式的组成部分

观察者模式通常包罗以下几个部分:


  • 主题(Subject):维护一组观察者,并在状态变化时通知所有观察者。
  • 观察者(Observer):界说一个更新接口,供主题在状态发生变化时调用。
  • 详细主题(ConcreteSubject):实现主题接口,保存状态,并在状态变化时通知观察者。
  • 详细观察者(ConcreteObserver):实现观察者接口,根据主题的状态变化做出相应。

三、用本身的话表明:如何理解观察者模式?

1. 类比实际生活中的场景

假设你是一家杂志的订阅者,每当这本杂志出书新一期时,你都会收到邮件通知。这时间,你是“观察者”,杂志社是“主题”,每当杂志社发布新内容时,它会通知所有订阅的读者。
在编程中,观察者模式通常应用于一对多的关系,当一个对象的状态变化时,其他对象会被通知并主动更新。比如,用户界面中一个输入框的值发生变化时,其他依赖于这个输入框值的组件(如显示结果的标签、搜索框等)会主动更新。
2. 为什么要使用观察者模式?

观察者模式的主要优势在于,它通过松耦合的方式管理对象之间的依赖关系。观察者与主题之间没有直接的毗连,主题只知道观察者的接口,不知道详细的实现,这使得体系更加灵活和可扩展。

四、深入理解:观察者模式的实现

接下来,我们通过一个详细的代码示例来实现观察者模式,资助你更好地理解如何在代码中使用这个模式。
示例:新闻推送体系

假设我们要开发一个新闻推送体系,用户可以订阅不同的新闻类型。当有新的新闻发布时,所有订阅该类型的用户都会收到通知。
1. 界说观察者接口

  1. # 观察者接口:定义更新方法
  2. class Observer:
  3.     def update(self, message: str):
  4.         pass
复制代码
2. 界说主题接口

  1. # 主题接口:定义注册、移除观察者的方法
  2. class Subject:
  3.     def register_observer(self, observer: Observer):
  4.         pass
  5.     def remove_observer(self, observer: Observer):
  6.         pass
  7.     def notify_observers(self):
  8.         pass
复制代码
3. 界说详细主题类:新闻发布

  1. # 具体主题类:新闻发布
  2. class NewsPublisher(Subject):
  3.     def __init__(self):
  4.         self._observers = []
  5.         self._latest_news = ""
  6.     def register_observer(self, observer: Observer):
  7.         self._observers.append(observer)
  8.     def remove_observer(self, observer: Observer):
  9.         self._observers.remove(observer)
  10.     def notify_observers(self):
  11.         for observer in self._observers:
  12.             observer.update(self._latest_news)
  13.     def set_latest_news(self, news: str):
  14.         self._latest_news = news
  15.         self.notify_observers()  # 状态变化时通知所有观察者
复制代码
4. 界说详细观察者类:用户

  1. # 具体观察者类:用户
  2. class User(Observer):
  3.     def __init__(self, name: str):
  4.         self._name = name
  5.     def update(self, message: str):
  6.         print(f"{self._name} received news: {message}")
复制代码
5. 客户端代码:订阅新闻

  1. # 创建新闻发布者实例
  2. news_publisher = NewsPublisher()
  3. # 创建用户实例
  4. user1 = User("Alice")
  5. user2 = User("Bob")
  6. # 用户订阅新闻
  7. news_publisher.register_observer(user1)
  8. news_publisher.register_observer(user2)
  9. # 发布新闻
  10. news_publisher.set_latest_news("Breaking: New python version released!")
  11. # 取消某个用户的订阅
  12. news_publisher.remove_observer(user2)
  13. # 再次发布新闻
  14. news_publisher.set_latest_news("Update: Python tutorial available!")
复制代码
代码解析:


  • Observer 类:这是观察者接口,界说了 update 方法,主题会通过这个方法通知观察者更新。
  • Subject 类:这是主题接口,界说了 register_observer、remove_observer 和 notify_observers 方法,用来管理观察者的注册、移除和通知。
  • NewsPublisher 类:这是详细的主题类,继续了 Subject,并实现了管理观察者和通知更新的逻辑。当有新的新闻发布时,它会调用 notify_observers 方法,通知所有注册的观察者。
  • User 类:这是详细的观察者类,继续了 Observer,当主题状态变化时,通过 update 方法接收到新新闻的通知。
  • 客户端代码:创建新闻发布者和多个用户,用户订阅新闻发布,发布者通知所有订阅的用户更新。

五、表明给别人:如何讲解观察者模式?

1. 用简单的语言表明

观察者模式就像是你订阅了一个新闻频道,每当有新新闻发布时,你都会收到通知。你不须要时刻查看新闻网站,而是当新闻变化时,你会主动收到更新。它让你能跟随某个变化的对象,而不消频仍地查询该对象。
2. 为什么要使用观察者模式?

使用观察者模式的利益是,它让体系的各个组件之间通过接口解耦。主题和观察者之间没有直接的依赖,主题只知道观察者的接口,并且通过通知机制来更新观察者。当有新观察者加入或脱离时,主题不须要做太多改动,从而提高了体系的灵活性和扩展性。

六、总结

通过一系列题目标引导,我们渐渐理解了观察者模式的核心思想和实现方式。观察者模式通过界说一对多的依赖关系,使恰当一个对象的状态发生变化时,所有依赖对象能够主动接收到通知并做出相应。它让体系更加松耦合,灵活且可扩展。
通过以上过程,我们可以得出以下结论:


  • 观察者模式 是一种行为型计划模式,它界说了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者都会得到通知并主动更新。
  • 它的主要优点是解耦、灵活性和扩展性,尤其适用于事件驱动或消息推送的场景。
  • 观察者模式的应用非常广泛,例如 GUI 组件、事件处置处罚、推送通知体系等。
观察者模式的优点:



  • 松耦合:观察者和主题之间没有直接依赖,便于扩展和维护。
  • 扩展性:可以灵活地增长或移除观察者,而不影响主题。
  • 易于实现:恰当实现一对多的通信关系,尤其在及时更新场景中非常有用。
观察者模式的缺点:



  • 大概导致性能题目:假如观察者数量非常多,大概会影响通知服从。
  • 依赖复杂:假如观察者和主题之间有太多复杂的依赖,大概会导致体系的理解和维护难度增长。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农民

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表