提供WeatherData对象,该对象能够获取目前的天气情况
(1)温度
(2)湿度
(3)气压
实现思路
//主体接口
public interface Subject {
public abstract void registerObserver(Observer ob);//注册
public abstract void removeObserver(Observer ob);//注销
public abstract void notifyObserver();//通知
}
//更新函数的接口,观察者
//出版者+订阅者=观察者模式
public interface Observer {
//public abstract是接口的默认的
public abstract void update(float temperature,float humidity,float pressure);
//这个接口只用于更新
}
//主体
import java.util.ArrayList;//集合类型的工具,作用是分配数组空间
public class WeatherData implements subject{
private float temperature; //温度
private float humidity; //湿度
private float pressure;//气压
private ArrayList<Observer> list;//可变数组,list是名字,ArrayList<Observer>是类型
//在数组里面放观察者类型,不明说是谁的类型,这就是接口的好处
//list中放的全是各个模版之间的联络方式,也就是地址,地址未带实值
//构造方法
public WeatherData() {
list = new ArrayList<Observer>();//数组实例化
}
//get,set方法
public float getTemperature(){
return temperature;
}
public float getHumidity(){
return humidity;
}
public float getPressure(){
return pressure;
}
public void setMeasurement(float t,float h,float p) {
this.temperature=t;
this.humidity=h;
this.pressure=p;
notifyObserver();
}
//可以编写其他方法
@Override
public void registerObserver(Observer ob) {//传入观察者
// TODO Auto-generated method stub
list.add(ob);//将指定元素追加到列表末尾
}
@Override
public void removeObserver(Observer ob) {
// TODO Auto-generated method stub
if(!list.isEmpty()) {//列表不为空,不为空的时候才能删,空表就没得删
boolean flag=list.remove(ob);//判断删除是否成功
if(!flag) {
System.out.println("删除失败!");
}
}
}
@Override
public void notifyObserver() {
// TODO Auto-generated method stub
for(Observer one:list) {
//调用数组中的每一组元素去干活,让每一个0ne都去调用update
//数组中装的是观察者模版,然后模版调用数据实现功能
//若是不用接口的话,每个模版都得调用update,同一组数据调用好几遍,墨迹,
//所以采用one.update()的方式
one.update(temperature,humidity,pressure);
}
}
}
//显示当前温度,湿度和气压
public class CurrentConditionsDisplay implements Observer{
//类和类之间的通信,当一个类想用另一个类,他们之间一定要有一个通信
public subject sub;
//可以写成public WeatherData sub;
public CurrentConditionsDisplay(Subject sub) {
this.sub=sub;
sub.register(this);
}
@Override
public void update(float temperature,float humidity,float pressure) {
// TODO Auto-generated method stub
System.out.println("温度:"+temperature+";湿度:"+humidity+";气压:"+pressure);
}
}
//显示出这一次的温度,湿度,气压,比上次高还是低
//这是附加的功能,可写可不写,算是程序的枝叶,不是主干
public class ForecastDisplay implements Observer{
private float newtemperature; //温度
private float lasttemperature;
private float newhumidity; //湿度
private float lasthumidity;
private float newpressure;//气压
private float lastpressure;
public subject sub;//主题
public ForecastDisplay(subject sub) {
this.sub=sub;
sub.registerObserver(this);//this是当前类的对象
}
public String d;
public String e;
public String f;
@Override
public void update(float temperature, float humidity, float pressure) {
// TODO Auto-generated method stub
this.newtemperature=temperature;
this.newhumidity=humidity;
this.newpressure=pressure;
if(newtemperature>lasttemperature ) {
d="高于";
}else if(newtemperature<lasttemperature ) {
d="低于";
}else if(newtemperature==lasttemperature) {
d="等于";
}
if(newhumidity>lasthumidity ) {
e="高于";
}else if(newhumidity<lasthumidity ) {
e="低于";
}else if(newhumidity==lasthumidity) {
e="等于";
}
if(newpressure>lastpressure ) {
f="高于";
}else if(newpressure<lastpressure ) {
f="低于";
}else if(newpressure==lastpressure) {
f="等于";
}
System.out.println("当前温度 "+d+" 之前温度 "+lasttemperature+","+"当前湿度 "+e+" 之前湿度 "+lasthumidity+" ,"+"当前气压 "+f+" 之前气压"+lastpressure);
lasttemperature=this.newtemperature;//给老数据赋上新数据的值
lasthumidity=this.newhumidity;
lastpressure=this.newpressure;
}
}
//显示温度的最大,最小,平均值
//这是附加的功能,可写可不写,算是程序的枝叶,不是主干
public class StatisticsDisplay implements Observer{
//显示温度的最大、最小及平均值
private float temperature; //温度
private float maxTem=0;//最大值设个小的,最小值设个大的
private float minTem=500;
private float sum=0;
private int count=0;
private float avg=0;
private float humidity; //湿度
private float pressure;//气压
public subject sub;//主题
//构造方法
public StatisticsDisplay(subject sub) {
this.sub=sub;
sub.registerObserver(this);//this是当前类的对象
}
//2.看是否有get,set方法,或其他方法
@Override
public void update(float temperature,float humidity,float pressure) {
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
if(temperature>maxTem) {
maxTem=temperature;
}
if(temperature<minTem) {
minTem=temperature;
}
sum=sum+this.temperature;
count=count+1;
display();
}
public void display() {
System.out.println("温度最大值:"+maxTem+";温度最小值"+minTem);
this.avg=sum/count;
System.out.println("平均值是:"+avg);
}
}
//运行
public class TestOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
WeatherData weather =new WeatherData();
CurrentConditionsDisplay current = new CurrentConditionsDisplay(weather);
ForecastDisplay fore =new ForecastDisplay(weather);
StatisticsDisplay stat=new StatisticsDisplay(weather);
weather.setMeasurement(14,70, 1010);
//每三秒一组数据(1000毫秒乘3)
try {
Thread.sleep(3*1000);//先打这一行,然后点×,选Surround with try/catch
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
weather.setMeasurement(17,70, 1011);
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
weather.setMeasurement(15,71, 1012);
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//weather.removeObserver(fore);//将fore这个模版销毁
}
}
结果:
写代码顺序:
(1)采用了观察者模型,先建立接口,接口分为主体接口和观察者接口;
(2)写主体函数WeatherData,主体函数实现主体接口
(3)写各个模版类,模版类实现观察者接口
(4)写运行类TestOne,输入数据进行测试