小标
2018-12-04
来源 :
阅读 1197
评论 0
摘要:本文主要向大家介绍了JAVA语言设计模式之观察者模式实例讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
本文主要向大家介绍了JAVA语言设计模式之观察者模式实例讲解,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
1. 引出问题
假设我们现在需要做一个实时天气预报的功能,并可以自定义任意多个显示界面。我们可以通过一个WeatherData的java类获取想要的信息,并将获取的相应信息分别显示在不同的界面。WeatherData的功能如下:
| 类名 | 获取温度方法 | 获取湿度方法 | 获取气压方法 | 通知更新方法 |
| WeatherData | getTempture | getHumidity | getPressure | measurementsChanged |
表中getXXX方法可以获取相应的信息,当天气发生变化时,measurementsChanges方法会被主动调用。
实现方案一:
public class WeatherData {
//略去实例变量声明
public void measurementsChanged() {
float temp = getTempture();
float humidity = getHumidity();
float pressure = getPressure();
//当前天气显示界面
currentConditionsDisplay.update(temp,humidity,pressure);
//数据分析建议界面
statisticsDisplay.update(temp,humidity,pressure);
//预报界面
forecastDisplay.update(temp,humidity,pressure);
}
//略去WeatherData的其他方法
}
根据之前提到的条件,天气发生变化时,measurementsChanged方法会被主动调用,我们直接在measurementsChanged方法里更新各个显示界面。
以上实现方法会遇到几个问题:
(1)当我们需要自定义新的显示界面时,就必须要修改WeatherDate类。
(2)根据策略模式中我们学到的知识,以上代码针对的是具体实现编程而不是接口,回想一下从策略模式学到的原则和概念。
(3)我们无法在运行时动态地增加或是删除指定的显示界面。
(4)我们破坏了WeatherData类的封装。
所以,实际开发中应该避免以上代码的使用。观察者模式正好解决了这部分问题。
2. 观察者模式
2.1 定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者收到通知并自动更新。
观察者模式中,被观察者,也可以说是被监听者称为主题,监听者称为观察者。如上情景中,WeatherData就是主题,而各种显示界面就是观察者。主题和观察者定义了一对多的。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知并更新自己的状态。
2.2 观察者模式类图
**UML图片使用的是ProcessOn绘制
2.3松耦合
当两个对象之间松耦合,他们仍然可以交互,但是不太清楚彼此的细节。观察者模式提供一种对象设计,让主题和观察者之间松耦合。
关于观察者的一切,主题只知道观察者实现了某个接口。主题不需要知道观察者的具体类是谁,有什么功能或者任何其他细节。
无论在什么时候观察者的增加,移除都不会对主题对象造成影响。这样我们就可以独立的复用主题或者观察者。如果我们在其他地方需要使用主题或者观察者,可以轻易的复用,因为二者并非时紧耦合的。
由此我们介绍一个新的设计原则:
为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。
3 解决问题
好了,我们开始设计天气预报以及显示的功能,在此之前,先看一下下面的设计图吧。
大家可以对照上面的设计图自己试着先写写代码。
首先,创建出两个接口,分别表示主题和观察者,主题接口如下:
public interface Subject {
public void registerObserver(Observer o);
public void unregisterObserver(Observer o);
public void notifyObservers();
}
观察者接口如下:
public interface Observer {
public void update(float tempture,float humidity,float pressure);
}
显示接口:
public interface DisplayElement {
public void display();
}
以上3个接口分别对应设计图上面三个interface。
然后我们需要实现主题接口,由于我们需要从WeatherData获取数据并显示在显示屏上,所以WeatherData是实现了主题接口的具体类:
package org.canvas.doit;
import java.util.ArrayList;
import java.util.List;
public class WeatherData implements Subject {
private List<observer> mObservers;
private float tempture;
private float humidity;
private float pressure;
public WeatherData() {
// TODO Auto-generated constructor stub
mObservers = new ArrayList<>();
}
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
if (o != null) {
mObservers.add(o);
}
}
@Override
public void unregisterObserver(Observer o) {
// TODO Auto-generated method stub
if (o != null) {
int index = mObservers.indexOf(o);
if (index >=0) {
mObservers.remove(o);
}
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
for(Observer observer : mObservers) {
observer.update(tempture, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
//此方法方便我们在测试过程中改变信息数值
public void setMeasurements(float tempture,float humidity,float pressure) {
this.tempture = tempture;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public float getTempture() {
return tempture;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
</observer>
WeatherData类实现了Subject接口,并使用List存储了所有观察者。setMeasurements函数只是方便我们后期测试,这里不是具体实现去网络上拉数据,有兴趣可以自己试着从网上拉取气象数据之后显示,有很多免费的api接口可以调用。
现在又了具体的主题类,下面我们就来设计一些具体的观察者类。
从设计上看,我们有三个观察这类,当前观测值的观察者类:
package org.canvas.doit;
public class CurrentConditionsDisplay implements Observer,DisplayElement {
private float tempture;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject subject) {
// TODO Auto-generated constructor stub
this.weatherData = subject;
weatherData.registerObserver(this);
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("Current conditions : "+tempture+" F degrees and "+humidity+"% humitidy");
}
@Override
public void update(float tempture, float humidity, float pressure) {
&n
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号