观察者模式-《Head First 设计模式》第二章
来源:互联网 发布:ysl高仿包包淘宝 编辑:程序博客网 时间:2024/06/08 00:01
问题汇总
- 定义
- 设计原则四:交互对象之间松耦合设计
- 如何使用?
- Java内置Observable(被观察者)缺点
- 观察者模式是如何利用设计原则的?
- 问题汇总
- 观察者模式
- 1-定义
- 2-设计原则四交互对象之间松耦合设计
- 3-优点
- 4-实例天气气象站数据在多个公告板的展示
- WetherDateSubject
- Obeserver
- 天气测量测试
- 5-实例利用Java内置观察者模式实现本文实例
- 被观察者Observerable发出通知的方法
- 观察者如何获取数据
- JavaWetherData
- JavaDisplayEnglish
- 数据测试
- 6-Java内置Observable缺点
- 7-观察者模式是如何利用设计原则的
- 针对接口编程
- 多组合少继承
观察者模式
观察者模式是JDK中使用最多的模式。
观察者模式类似于报社的运行方式,订阅者一开始在报社考起了订阅服务,当报社每天获得新报纸之后,会给所有用户派送报纸,如果用户不想继续看报纸了,也可以去报社退订。这种就是观察者模式:
出版者 + 订阅者 = 观察者模式
出版者就是主题Subject,订阅者就是观察者Observer
Subject + Observer = 观察者模式
1-定义
定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
2-设计原则四:交互对象之间松耦合设计
3-优点
- Subject拥有数据并读取,不需要让多个Object操作同一份数据,干净安全
- 可以独立的复用Subject和Observer
4-实例:天气气象站数据在多个公告板的展示
结构:天气气象站就是Subject,当数据变动时,通知所有公告牌进行显示。公告牌就是Observer,设计一个Observer接口和element接口(抽象公告牌的共同部分)。
WetherDate(Subject)
public interface Subject { public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifycation();}public class WetherData implements Subject{ float temp = 0; float humidity = 0; boolean isChanged = false; ArrayList<Observer> observerList = new ArrayList<>(); //注册观察者就是在链表中添加观察者 public void registerObserver(Observer observer) { observerList.add(observer); } //移除观察者 public void removeObserver(Observer observer) { int index = observerList.indexOf(observer); observerList.remove(index); } //通知所有观察者 public void notifycation() { if(isChanged) { for(Observer observer:observerList) { observer.update(temp, humidity); } isChanged = false; } } public void measureDataChanged(float temp, float humidity) { this.temp = temp; this.humidity = humidity; isChanged = true; notifycation(); }}
Obeserver
//观察者接口public interface Observer { public void update(float temp, float humidity);}//告示牌通用功能public interface DisplayElement { public void display();}//中文版告示牌public class DisplayChinese implements Observer, DisplayElement{ float temp = 0; float humidity = 0; public DisplayChinese(WetherData wetherData) { wetherData.registerObserver(this); } public void display() { System.out.println("中文数据:当前温度:"+temp+"℃/当前湿度:"+humidity+"%"); } public void update(float temp, float humidity) { this.temp = temp; this.humidity = humidity; display(); }}//英文版告示牌public class DisplayEnglish implements Observer, DisplayElement{ float temp = 0; float humidity = 0; public DisplayEnglish(WetherData wetherData) { wetherData.registerObserver(this); } public void display() { System.out.println("English data:temp:"+temp+"℃/humi:"+humidity+"%"); } public void update(float temp, float humidity) { this.temp = temp; this.humidity = humidity; display(); }}
天气测量(测试)
public class WetherMeasure { public static void main(String[] args) { WetherData wetherData = new WetherData(); DisplayEnglish beijingDisplay = new DisplayEnglish(wetherData); DisplayChinese nanjingDisplay = new DisplayChinese(wetherData); wetherData.measureDataChanged(20, 60); }}
运行结果:
English data:temp:20.0℃/humi:60.0%
中文数据:当前温度:20.0℃/当前湿度:60.0%
- 可以看到结果显示正确
5-实例:利用Java内置观察者模式,实现本文实例
Java内置支持观察者模式,在包java.util.Observable
中。
在Java中,Subject用Observable
表示,意思可以理解为被观察者。而观察者依然是Observer
。
被观察者(Observerable)发出通知的方法
- 先调用
setChanged()
方法 - 调用
notifyObservers()
观察者如何获取数据
与我们实现的方法不同,Java内置观察者的方法是观察者去主动获取数据。比如在update
中去get
数据,而不是由被观察者来推送数据。
JavaWetherData
public class JavaWetherData extends Observable{ float temp = 0; float humi = 0; //提供获取数据接口 public float getTemp() { return temp; } public float getHumi() { return humi; } public void measureData(float temp, float humi) { this.temp = temp; this.humi = humi; setChanged(); //改变标志 notifyObservers();//推送通知 }}
JavaDisplayEnglish
实现Java提供的Observer
接口
public class JavaDisplayEnglish implements Observer, DisplayElement{ float temp = 0; float humi = 0; public JavaDisplayEnglish(Observable observable) { observable.addObserver(this); //在被观察者中进行注册 } public void display() { System.out.println("(Java内置观察者)English data:temp:"+temp+"℃/humi:"+humi+"%"); } //更新数据-主动去获取数据 public void update(Observable arg0, Object arg1) { if(arg0 instanceof JavaWetherData) { //确保参数正确 JavaWetherData wetherData = (JavaWetherData)arg0; temp = wetherData.getTemp(); humi = wetherData.getHumi(); display(); } }}
数据测试
JavaWetherData javaWetherData = new JavaWetherData();JavaDisplayEnglish javaDisplayEnglish = new JavaDisplayEnglish(javaWetherData);javaWetherData.measureData(23, 79);
(Java内置观察者)English data:temp:23.0℃/humi:79.0%
结果正确,这样就实现了观察者模式。但是这种方法是有缺陷的。
6-Java内置Observable缺点
- Observable是一个类而不是interface,影响了复用和使用。
- 违反了
多用组合,少用继承
的原则。
7-观察者模式是如何利用设计原则的?
1.针对接口编程
Observer观察者利用主题的接口向Subject进行注册。
Subject使用Observer的接口通知观察者
2.多组合少继承
对象之间的关系不是通过继承产生,而是在运行时通过组合来产生。
- Head First设计模式第二章——观察者模式
- 观察者模式-《Head First 设计模式》第二章
- [设计模式]head first 设计模式之PHP实现 第二章 观察者模式
- Head First设计模式C++实现--第二章:观察者(Oserver)模式
- head first 设计模式:观察者模式1
- Head First设计模式-观察者模式
- 《Head First 设计模式》观察者模式
- Head First 设计模式笔记--观察者模式
- 《Head First 设计模式》之观察者模式
- Head First 设计模式2 观察者模式
- 《Head First 设计模式》之观察者模式
- <Head First 设计模式>:观察者模式--Weather
- Head First设计模式—观察者模式
- 【Head First设计模式-读书笔记】观察者模式
- Head First设计模式---策略、观察者模式
- Head First 设计模式-观察者模式
- 《Head First设计模式》 - 观察者模式
- head first设计模式之观察者模式
- mysql group replication 单写模式 (single-primary mode) 搭建
- JQuery 对 Select option 的操作
- 移动端判断设备
- 十分钟搞定pandas
- HTML5+CSS3的响应式网页设计:自动适应屏幕宽度
- 观察者模式-《Head First 设计模式》第二章
- selenium win7 环境搭建总结
- Spring3.1新特性。
- 安装mysql方法
- APK瘦身优化,减小apk的大小
- nodejs中使用bcrypt加密
- Git 最基础入门--创建本地仓库上传文件
- [数据库]Bulk Insert命令详细
- SOAP-ERROR: Parsing WSDL:Couldn’t load from “xxxxxxx” 解决方案