观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package com.observer; /** * 这个是核心类(可以理解成气象观测站,他这里有最新的天气情况) * 1.包含最新的天气情况信息 * 2.含有CurrentConditions 对象 * 3.当数据有更新的时候,就主动的调用 CurrentConditions 对象的 update方法(含display方法),这样他们(接入方)就看到了最新的信息 * */ public class WeatherData { private float temperature; //温度 private float pressure; //气压 private float humidity; //湿度 private CurrentConditions currentConditions; public WeatherData(CurrentConditions currentConditions){ this .currentConditions=currentConditions; } public float getTemperature() { return temperature; } public float getPressure() { return pressure; } public float getHumidity() { return humidity; } public void dataChange(){ //调用接入方的update() currentConditions.update(getTemperature(),getPressure(),getHumidity()); } //当有数据更新的时候,就调用setData public void setData( float temperature, float pressure, float humidity){ this .temperature=temperature; this .pressure=pressure; this .humidity=humidity; //调用dataChange,将最新的信息 推送给 接入方(也就是currentConditions) dataChange(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.observer; /** * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】) */ public class CurrentConditions { private float temperature; //温度 private float pressure; //气压 private float humidity; //湿度 //更新天气情况,是由WeatherData类来调用,使用推送模式 public void update( float temperature, float pressure, float humidity){ this .temperature=temperature; this .pressure=pressure; this .humidity=humidity; //更新完成之后,进行展示 display(); } //显示 private void display() { System.out.println( "today temperature:" +temperature); System.out.println( "today pressure:" +pressure); System.out.println( "today humidity:" +humidity); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.observer; import com.alibaba.fastjson.JSON; import java.util.Map; /** * 模拟客户端进行调用 */ public class Client { public static void main(String[] args) { //创建接入方 CurrentConditions CurrentConditions currentConditions = new CurrentConditions(); //创建 WeatherData 并将接入方 currentConditions 传递到WeatherData中去 WeatherData weatherData = new WeatherData(currentConditions); //更新天气情况 weatherData.setData( 30 , 100 , 50 ); //天气发生变化 System.out.println( "=====天气发生变化=====" ); weatherData.setData( 20 , 200 , 60 ); } } |
运行结果:
1 2 3 4 5 6 7 | today temperature: 30.0 today pressure: 100.0 today humidity: 50.0 =====天气发生变化===== today temperature: 20.0 today pressure: 200.0 today humidity: 60.0 |
代码
1 2 3 4 5 6 7 | package com.observer.improve; //接口,让WeatherData来实现 public interface Subject { public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObservers(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | package com.observer.improve; import com.observer.CurrentConditions; import java.util.ArrayList; /** * 这个是核心类(可以理解成气象观测站,他这里有最新的天气情况) * 1.包含最新的天气情况信息 * 2.含有观察者集合,使用Arraylist管理 * 3.当数据有更新的时候,就主动的调用 Arraylist, 通知所有的接入方,就能够看到最新的信息 */ public class WeatherData implements Subject { private float temperature; //温度 private float pressure; //气压 private float humidity; //湿度 private ArrayList<Observer> observers; //观察者集合 public WeatherData() { observers = new ArrayList<Observer>(); } public float getTemperature() { return temperature; } public float getPressure() { return pressure; } public float getHumidity() { return humidity; } public void dataChange() { //调用接入方的update() notifyObservers(); } //当有数据更新的时候,就调用setData public void setData( float temperature, float pressure, float humidity) { this .temperature = temperature; this .pressure = pressure; this .humidity = humidity; //调用dataChange,将最新的信息 推送给 接入方(也就是currentConditions) dataChange(); } //下面这三个是核心的方法 /** * 注册一个观察者 * * @param observer */ @Override public void registerObserver(Observer observer) { observers.add(observer); } /** * 移除一个观察者 * * @param observer */ @Override public void removeObserver(Observer observer) { if (observers.contains(observer)) { observers.remove(observer); } } /** * 遍历所有的观察者,并进行通知 */ @Override public void notifyObservers() { for ( int i = 0 ; i <observers.size() ; i++) { observers.get(i).update( this .temperature, this .pressure, this .humidity); } } } |
1 2 3 4 5 | package com.observer.improve; //观察者接口,由观察者来实现 public interface Observer { public void update( float temperature, float pressure, float humidity); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.observer.improve; /** * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】) */ public class CurrentConditions implements Observer{ private float temperature; //温度 private float pressure; //气压 private float humidity; //湿度 //更新天气情况,是由WeatherData类来调用,使用推送模式 public void update( float temperature, float pressure, float humidity){ this .temperature=temperature; this .pressure=pressure; this .humidity=humidity; //更新完成之后,进行展示 display(); } //显示 private void display() { System.out.println( "today temperature:" +temperature); System.out.println( "today pressure:" +pressure); System.out.println( "today humidity:" +humidity); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package com.observer.improve; /** * 百度网站 * 显示当前天气情况(可以理解成是气象局自己的网站需要展示天气情况【当然还有百度、新浪等网站也需要展现天气情况】) */ public class BaiduCurrentConditions implements Observer{ private float temperature; //温度 private float pressure; //气压 private float humidity; //湿度 //更新天气情况,是由WeatherData类来调用,使用推送模式 public void update( float temperature, float pressure, float humidity){ this .temperature=temperature; this .pressure=pressure; this .humidity=humidity; //更新完成之后,进行展示 display(); } //显示 private void display() { System.out.println( "百度首页气象信息" ); System.out.println( "baidu today temperature:" +temperature); System.out.println( "baidu today pressure:" +pressure); System.out.println( "baidu today humidity:" +humidity); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.observer.improve; public class Client { public static void main(String[] args) { //创建一个weatherdata WeatherData weatherData = new WeatherData(); //创建一个观察者 CurrentConditions currentConditions = new CurrentConditions(); BaiduCurrentConditions baiduCurrentConditions = new BaiduCurrentConditions(); //将观察者注册到weatherdata中 weatherData.registerObserver(currentConditions); weatherData.registerObserver(baiduCurrentConditions); //测试 System.out.println( "通知各个注册的观察者,看看收到的信息" ); weatherData.setData( 10 , 100 , 32 ); weatherData.removeObserver(currentConditions); System.out.println( "通知各个注册的观察者,看看收到的信息" ); weatherData.setData( 10 , 100 , 32 ); } } |
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 通知各个注册的观察者,看看收到的信息 today temperature: 10.0 today pressure: 100.0 today humidity: 32.0 百度首页气象信息 baidu today temperature: 10.0 baidu today pressure: 100.0 baidu today humidity: 32.0 通知各个注册的观察者,看看收到的信息 百度首页气象信息 baidu today temperature: 10.0 baidu today pressure: 100.0 baidu today humidity: 32.0 |
观察者模式的好处
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2020-09-07 违反完整约束条件***已找到子记录的删除方法