观察者模式一:
观察者模式所含的两个重要元素:
(1)观察者:将接收“主题”类传递进来的更新数据
(2)主题(被观察者):当数据更新时,将通知他的观察者对象列表中的所有对象。观察者对象接收到更新数据时将做出一系列反应,主题是真正含有数据的类。
注:观察者和被观察者(主题)之间是松耦合关系,被观察者(主题)只关注观察者实现了哪一个类,而不关心她是如何实现的,以及观察者中含有哪些方法。(主题之所以要关注观察者实现了哪一个接口,是因为主题要在“通知观察者数据更新的方法”中调用观察者类的更新方法来响应主题发来的更新数据(即告诉主题自己已经收到更新数据的信息))
观察者模式的代码示例:
public interface Observer //观察者接口,实现它的类可以调用update方法更新从“主题”类所接受的数据
{
public void update(float temp,float humidity,float pressure); //“观察者”对象通过该方法更新从“主题类所接收到”的数据
}
public interface displayelement //该接口提供display方法让观察者对从“主题”类接受到的数据进行操作和显示
{
public void display(); //让观察者对象显示从“主题”类接受到的数据
}
public interface Subject //“主题”接口,真正“拥有”数据的类
{
public void registerobserver(Observer o); //通过该方法注册观察者,使得以后调用notifyobservers()方法能够通知到这个对象
public void removeobserver(Observer o); //通过该方法将某个对象移除观察者对象列表,使得以后调用notifyobservers()方法时不会再通知到该对象
public void notifyobservers(); //通过该方法通知观察者对象列表中的对象
}
public class WeatherData implements Subject //具体“主题”类
{
private float temp;
private float humidity;
private float pressure;
private ArrayList observers; //观察者对象的集合,该集合用于存放“含有一系列能够接受到“主题”类所发数据的观察者对象”
//(在这里体现了观察者模式一对多的关系)在具体“主题”类中含有“观察者”类的对象引用
public WeatherData()
{
observers=new ArrayList();
}
@Override
public void registerobserver(Observer o)
{
observers.add(o); //从观察者集合中增加新的观察者对象;
}
@Override
public void removeobserver(Observer o)
{
observers.remove(o); //从观察者集合中删除要删除的观察者对象;
}
@Override
public void notifyobservers()
{
for(int i=0;i<observers.size();i++) //将所有的具体观察者对象遍历一遍
{
Observer observer=(Observer)observers.get(i); //该方法用于将更新消息传达到各个观察者对象
observer.update(temp, humidity, pressure); //通过观察者对象调用观察者类的update方法
}
}
public void measurementschanged(float temp,float humidity,float pressure)
{
this.humidity=humidity;
this.temp=temp;
this.pressure=pressure;
notifyobservers(); //当数据更新时,调用notifyobservers方法,通知各观察者
}
public float gettemp()
{
return this.temp;
}
public float getHumidity()
{
return this.humidity;
}
public float getpressure()
{
return pressure;
}
}
public class currentcondition implements Observer,displayelement //具体观察者
{
private float temp;
private float humidity;
private Subject weatherData; //具体观察者类中含有一个“主题类”的对象引用,
public currentcondition(Subject weatherData) //面向接口编程思想,后期传入的其实是一个实现“主题类”的“具体主题类”
{
this.weatherData=weatherData;
weatherData.registerobserver(this); //将该具体主题类注册成一个观察者,以便能接收“主体传送进来的数据”
}
public currentcondition()
{
}
@Override
public void update(float temp, float humidity, float pressure) //实现更新方法,用于更新从“主题类”传递过来的数据
{
this.temp=temp;
this.humidity=humidity;
display();
}
@Override
public void display() //该方法用于处理观察者对象接收到的主题类的数据
{
System.out.println("当前状况");
System.out.println("当前温度为:"+temp);
System.out.println("当前湿度为:"+humidity);
}
}
public class statisticsdisplay implements Observer,displayelement
{
private float zuigaotemp;
private float zuiditemp;
private Subject weatherdata;
public statisticsdisplay()
{
}
public statisticsdisplay(Subject weatherdata)
{
this.weatherdata=weatherdata;
weatherdata.registerobserver(this);
}
@Override
public void update(float zuigaotemp, float zuiditemp, float pressure)
{
this.zuigaotemp=zuigaotemp;
this.zuiditemp=zuiditemp;
display();
}
@Override
public void display()
{
System.out.println("天气统计");
System.out.println("最高温度为:"+zuigaotemp);
System.out.println("最低温度为:"+zuiditemp);
System.out.println("平均温度为:"+(zuigaotemp+zuiditemp)/2);
}
}
public class WeatherStation
{
public static void main(String[] args) {
// TODO code application logic here
currentcondition curr=new currentcondition();
statisticsdisplay stat=new statisticsdisplay();
WeatherData weatherdata=new WeatherData(); //创建一个具体主题对象
//currentcondition curr=new currentcondition(weatherdata); //通过具体观察者的构造方法,将该具体观察者注册为一个观察者
weatherdata.registerobserver(stat);
weatherdata.registerobserver(curr);
weatherdata.measurementschanged(25, 80, 0);
weatherdata.removeobserver(curr);
weatherdata.measurementschanged(55,55,0);
}
}