观察者模式——气象局高温预警

来源:互联网 发布:java源代码下载 编辑:程序博客网 时间:2024/04/30 13:36

一模式定义

观察者模式,又称为发布/订阅模式。观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

 

二模式举例

1 模式分析

我们借用气象局高温预警来说明这一模式。



 

2观察者模式静态类图


 

3代码示例

3.1观察者接口一IObserver

package com.demo.observer;import com.demo.subject.ISubject;/** * 观察者接口 * @author  * */public interface IObserver{//更新方法public void update(ISubject subject);}

3.2主题接口一ISubject

package com.demo.subject;import com.demo.observer.IObserver;/** * 主题接口(被观察者) *  * @author *  */public interface ISubject{/** * 增加观察者 *  * @param observer * @return */public boolean add(IObserver observer);/** * 删除观察者 *  * @param observer * @return */public boolean remove(IObserver observer);/** * 通知所有观察者更新数据 */public void notifyAllObserver();/** * 设置温度值 *  * @param temperature */public void setTemperature(float temperature);/** * 获得温度预警 *  * @return */public String temperatureReport();}

3.3具体主题实现一Subject

package com.demo.subject;import java.util.Iterator;import java.util.Vector;import com.demo.observer.IObserver;/** * 主题实现类(被观察者) *  * @author *  */public class Subject implements ISubject {// 温度/** * (一)高温黄色预警信号 *  * 标准:连续三天日最高气温将在35℃以上。 *  * (二)高温橙色预警信号 *  * 标准:24小时内最高气温将升至37℃以上。 *  * (三)高温红色预警信号 *  * 标准:24小时内最高气温将升至40℃以上。 */private float temperature;// 预警级别private String warningLevel;// 保存观察者列表private final Vector<IObserver> vector;/** * 构造方法 初始化观察者列表 */public Subject() {vector = new Vector<IObserver>();}/** * 增加观察者 */public boolean add(IObserver observer) {if (observer != null && !vector.contains(observer)) {return vector.add(observer);}return false;}/** * 移除观察者 */public boolean remove(IObserver observer) {return vector.remove(observer);}/** * 通知所有观察者更新数据 */public void notifyAllObserver() {System.out.println("======气象部门发布高温" + this.warningLevel + "警报!======");Iterator<IObserver> iterator = vector.iterator();while (iterator.hasNext()) {(iterator.next()).update(this);}}/** * 私有方法 根据温度值设置预警级别 然后通知所有观察者 */private void invoke() {if (this.temperature >= 35) {if (this.temperature >= 35 && this.temperature < 37) {this.warningLevel = "黄色";} else if (this.temperature >= 37 && this.temperature < 40) {this.warningLevel = "橙色";} else if (this.temperature >= 40) {this.warningLevel = "红色";}// 通知所有观察者温度状况this.notifyAllObserver();}}/** * 设置温度值 *  * @param temperature */public void setTemperature(float temperature) {this.temperature = temperature;this.invoke();}/** * 获得温度预警 */public String temperatureReport() {return " 温度:" + this.temperature;}}

3.4个人观察者一PersonObserver

package com.demo.observer;import com.demo.subject.ISubject;/** * 个人用户观察者 * @author  * */public class PersonObserver implements IObserver{public void update(ISubject subject){System.out.println("个人收到高温预警:" + subject.temperatureReport());}}

3.5政府观察者一GovernmentObserver

package com.demo.observer;import com.demo.subject.ISubject;/** * 政府用户观察者 * @author  * */public class GovernmentObserver implements IObserver{public void update(ISubject subject){System.out.println("政府部门收到高温预警:" + subject.temperatureReport());}}

3.6企事业单位观察者一CompanyObserver

package com.demo.observer;import com.demo.subject.ISubject;/** * 企事业单位用户观察者 * @author  * */public class CompanyObserver implements IObserver{public void update(ISubject subject){System.out.println("企事业单位收到高温预警:" + subject.temperatureReport());}}

3.7让系统开始运行一Client

package com.demo;import java.util.Random;import com.demo.observer.CompanyObserver;import com.demo.observer.GovernmentObserver;import com.demo.observer.PersonObserver;import com.demo.subject.ISubject;import com.demo.subject.Subject;/** * 客户端应用 *  * @author *  */public class Client {/** * @param args */public static void main(String[] args) {// 创建主题对象ISubject subject = new Subject();// 增加企事业单位观察者subject.add(new CompanyObserver());// 增加政府用户观察者subject.add(new GovernmentObserver());// 增加个人用户观察者subject.add(new PersonObserver());Random random = new Random();int i = 0;while (++i < 10) {// 设置随机温度subject.setTemperature(random.nextInt(45));}}}

4运行结果

======气象部门发布高温黄色警报!======

企事业单位收到高温预警: 温度:35.0

政府部门收到高温预警: 温度:35.0

个人收到高温预警: 温度:35.0

======气象部门发布高温红色警报!======

企事业单位收到高温预警: 温度:43.0

政府部门收到高温预警: 温度:43.0

个人收到高温预警: 温度:43.0

======气象部门发布高温橙色警报!======

企事业单位收到高温预警: 温度:37.0

政府部门收到高温预警: 温度:37.0

个人收到高温预警: 温度:37.0

 

三该模式设计原则

1"开——闭"原则

2单一职责原则

3依赖倒置原则

 

四使用场合

1当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,需要将这两个方面分别封装到独立对象中,彼此独立地改变和复用的时候。

2当一个系统中一个对象的改变需要同时改变其他对象内容,但又不知道待改变对象到底有多少个的时候。

3当一个对象的改变必须通知其他对象做出相应的变化,但是不能确定通知对象是谁的时候。

 

五"推数据"静态类图

所谓"推数据",就是当被观察对象发生改变时,将相关数据通过参数形式传递给观察者,这就形成了被观察者"推数据"给观察者,静态类图如下:



 

六"拉数据"静态类图

所谓"拉数据",观察者对象含有一个对被观察者对象实例的引用,当被观察者对象发生变化时,不会传递任何数据给观察者,而由观察者根据被观察者对象实例的引用主动获取相关的数据,这就形成了观察者主动从被观察对象中"拉数据“,静态类图如下:



 

原创粉丝点击