当前位置: 首页 > news >正文

设计模式 四、行为设计模式(1)

        在设计模式的世界里,23种经典设计模式通常被分为三大类:创建型、结构型和行为型。创建型设计模式关注对象创建的问题,结构性设计模式关注于类或对象的组合和组装的问题,行为型设计模式则主要关注于类或对象之间的交互问题。

        行为设计模式 的数量较多,共有11种,几乎占据了23种经典设计模式的一半。这些模式分别为:观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、访问者模式、备忘录模式、命令模式、解释器模式和中介模式。

一、观察者模式

        1、概述

        观察者模式是一种行为设计模式,允许对象间存在一对多的依赖关系当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新,在这种设计模式种,发生状态改变的对象被称为“主题”(Subject),依赖它的对象成为“观察者”(Observer)。

        观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。在GoF的设计模式书中,它的定义是这样的:

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

        翻译成中文就是说:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

        一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项目开发中,这两种对象的称呼是比较灵活的,有各种不同的叫法,比如:Subject-Observer 、Publisher-Subscriber、Producer-Consumer等等。不管怎么称呼,只要应用场景符合刚刚给出的定义,都可以看作观察者模式。

        简单例子:假设我们有一个气象站,需要向许多不同的显示设备(如手机App、网站、电子屏幕等)提供实施天气数据。

         首先我们创建一个Subject接口,表示主题:

    public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();}

        接下来,创建一个Observer接口,表示观察者:

public interface Observer {void update(float temperature, float humidity, float pressure);
}

        创建一个具体的主体,如WeatherStation,实现Subject接口:

public class WeatherStation implements Subject {private ArrayList<Observer> observers;// 温度private float temperature;// 湿度private float humidity;// 大气压private float pressure;public WeatherStation() {observers = new ArrayList<>();}// 注册一个观察者的方法@Overridepublic void registerObserver(Observer o) {observers.add(o);}// 移除一个观察者的方法@Overridepublic void removeObserver(Observer o) {int index = observers.indexOf(o);if (index >= 0) {observers.remove(index);}}// 通知所有的观察者@Overridepublic void notifyObservers() {// 循环所有的观察者,通知其当前的气象信息for (Observer o : observers) {o.update(temperature, humidity, pressure);}}// 修改气象内容public void measurementsChanged() {notifyObservers();}// 当测量值发生了变化的时候public void setMeasurements(float temperature, float humidity, floatpressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;// 测量值发生了变化measurementsChanged();}
}

         最后我们创建一个具体的观察者,如PhoneAPP,实现Observer接口:

public class PhoneApp implements Observer {private float temperature;private float humidity;private float pressure;private Subject weatherStation;public PhoneApp(Subject weatherStation) {this.weatherStation = weatherStation;weatherStation.registerObserver(this);}@Overridepublic void update(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;display();}public void display() {System.out.println("PhoneApp: Temperature: " + temperature + "°C,Humidity: " + humidity + "%, Pressure: " + pressure + " hPa");}
}

        现在我们可以创建一个WeatherStation实例并向其注册PhoneApp观察者。当WeatherStation的数据发生变化时,PhoneApp会收到通知并更新自己的显示。

public class Main {public static void main(String[] args) {WeatherStation weatherStation = new WeatherStation();PhoneApp phoneApp = new PhoneApp(weatherStation);// 模拟气象站数据更新weatherStation.setMeasurements(25, 65, 1010);weatherStation.setMeasurements(22, 58, 1005);// 添加更多观察者 网站上显示-电子大屏WebsiteDisplay websiteDisplay = new WebsiteDisplay(weatherStation);ElectronicScreen electronicScreen = new ElectronicScreen(weatherStation);// 再次模拟气象站数据更新weatherStation.setMeasurements(18, 52, 1008);}
}

        这个例子中,我们创建了一个WeatherStation实例,并向其注册了PhoneApp、WebsiteDisplay和ElectronicScreen观察者,当WeatherStation的数据发生变化这个例子展示了观察者模式的优点:
        1)观察者和主题之间解耦:主题只需要知道观察者实现了Observer接口,而无需了解具体的实现细节。
        2)可以动态的添加和删除观察者:通过调用registerObserver 和 removeObserver方法,可以在运行时添加和删除观察者。
        3)主题和观察者之间的通信时自动的:当主题的状态发生变化时,观察者会自动得到通知并更新自己的状态。

        观察者广泛应用于各种场景,例如事件处理系统、数据同步和更新通知等。上面例子算是观察者模式的 “模板代码”,可以反应该模式大体得设计思路,在真实得软件开发中,并不需要照搬相面的模板代码。观察者模式的实现方法各式各样, 函数、类的命名等会根据业务场景的不同有很大的差别,比如 register 函数还可以 叫作 attachremove 函数还可以叫作 detach 等等。不过,万变不离其宗,设计思 路都是差不多的。

        了解了观察者设计模式的基本使用方式,我们接下来看看他的具体使用场景

        简单理解: Subject 代表主动要做的事,比如要更新某个状态,主动触发某个行为。实现Observer 接口,代表被动触发得事,也可以理解为待办事项,比如我修改了某个状态,就要被动得触发一些事情,比如支付成功,就要将订单状态置为已完成等等。我们通过 Observe 中的registerObserver方法将待办事项加入到 Subject 中,然后当 Subject 主动做某项事情时,就会调用notifyObservers方法 将已经添加的待办事项都调用一下。

        2、使用场景

        1)股票行情应用:股票行情应用中,当股票价格发生变化时,需要通知订阅了该股票得投资者。这里,股票价格更新可以作为被观察者,投资者可以作为观察者。当股票发生变化时,所有订阅了该股票的投资者都会收到通知并更新自己的投资策略。

        2)网络聊天室:在网络聊天室中,当有新消息时,需要通知所有在线用户。聊天室服务器可以作为被观察者,用户可以作为观察者。当有新消息时,聊天室服务会通知所有在线用户更新聊天记录。

        3)拍卖系统:在拍卖系统中,当出价发生变化时,需要通知所有关注该拍品得用户。这里,拍卖系统可以作为被观察者,用户可以作为观察者。当出价发生变化时,所有关注该拍品得用户都会收到通知并更新自己的出价策略。

        4)订阅系统:在订阅系统中,当有新的内容发布时,需要通知所有订阅了该内容得用户,这里,内容发布可以作为被观察者,用户可以作为观察者,当有新内容发布时,所有订阅了该内容得用户都会收到通知并获取最新内容。

        5)游戏中的事件系统:在游戏中,当某个事件发生时(如角色升级、道具获得等),可能需要通知多个游戏模块进行相应的处理。这里,游戏事件可以作为被观察者,游戏模块可以作为观察者。当游戏事件发生时,所有关注该事件的游戏模块都会收到通知并执行相应的逻辑。

        6)运动比赛实时更新:在体育比赛中,实时更新比分、技术统计等信息对于球迷和分析师非常重要。在这种场景下,比赛数据更新可以作为被观察者,球迷和分析师可以作为观察者。当比赛数据发生变化时,所有关注比赛的的球迷和分析师都会收到通知并更新数据。

        7)物联网传感器系统:在物联网(IoT)系统中,有很多传感器不断采集数据,当数据发生变化时,需要通知相关联的设备或系统。在这种场景下,传感器可以作为被观察者,关联的设备或系统可以作为观察者,当传感器发生变化时,所有关联的设备或系统都会收到通知并执行相应的操作。

        8)电子邮件通知系统:在一个任务管理系统中,当任务的状态发生变化(如:新任务分配、任务完成等)时,需要通知相关的人员。这里,任务状态变更可以作为被观察者,相关人员可以作为观察者。当任务状态发生变化时,所有关注者都会收到通知并查看任务详情。

        9)社交网络:在社交网络中,用户关注其他用户以获取实时动态。当被关注的用户发布新动态时,需要通知所有关注者,在这种场景下,被关注的用户可以作为被观察者,关注者可以作为观察者,当被关注用户发布新动态时,所有关注者都会收到通知并查看动态。


http://www.mrgr.cn/news/97495.html

相关文章:

  • AI烘焙大赛中的算法:理解PPO、GRPO与DPO最简单的方式
  • Python 之 Pandas 常用操作
  • 项目难点亮点
  • 大数据(5)Spark部署核弹级避坑指南:从高并发集群调优到源码级安全加固(附万亿级日志分析实战+智能运维巡检系统)
  • 英语学习 4.7
  • 红宝书第三十一讲:通俗易懂的包管理器指南:npm 与 Yarn
  • C#结合SQLite数据库使用方法
  • C++11实现一个自旋锁
  • 压测工具开发实战篇(四)——client子窗口功能
  • 本地大模型构建个人知识库(Ragflow)
  • 屏幕空间反射SSR-笔记
  • 【C++】Chapter04<STL部分>:STL标准模板库概要
  • Python数据爬取
  • 从搜索丝滑过渡到动态规划的学习指南
  • 测开八股收集
  • 3D激光轮廓仪知识整理(待补充)
  • 代码随想录算法训练营第十一天
  • 2025-04-07 NO.3 Quest3 MR 配置
  • 《从零搭建Vue3项目实战》(AI辅助搭建Vue3+ElemntPlus后台管理项目)零基础入门系列第二篇:项目创建和初始化
  • RAG中构建个人知识库