面试题:用Java语言模拟一个观察者模式。
先看测试程序:
有一个被观测的对象天气类——Whether
两个天气观察者——WhetherDisplay1,WhetherDisplay2。
天气改变后,两个观察者输出观察结果。
public class Test {
public static void main(String[] args) {
Whether whether=new Whether(); //实例化被观察对象 天气类 whether
WhetherDisplay1 d1=new WhetherDisplay1(whether); //实例化两个天气观察者 d1 与 d2
WhetherDisplay2 d2=new WhetherDisplay2(whether);
whether.setTemperature(27); // 天气类,变化 27度,26度。两个观察者d1 d2.观察到变化立即输出27.0 ,26.0
whether.setTemperature(26);
}
}
输出结果:
模拟观察者模式需要先写两个接口 Subject与Observer
Subject接口是被观察者接口,天气类Whether实现了这个接口。
Observer是观察者接口, WhetherDisplay1,WhetherDisplay2实现了这个接口。
Observer接口:
public interface Observer {
public void update(float temp); //更新天气情况
}
Subject接口:
public interface Subject {
public void registerObserver(Observer o); //注册一个观察者。
public void removeObserver(Observer o); //移除一个观察者。
public void notifyObservers(); //温度发生改变时,通知观察者。
}
Whether类实现了Subject接口
import java.util.ArrayList;
public class Whether implements Subject {
//一个观察者列表,用于储存观察者对象*
private ArrayList<Observer>observers=new ArrayList<Observer>();
private float temperature; //温度属性
@Override //重写注册方法,注册一个观察者。
public void registerObserver(Observer o) {
this.observers.add(o); //将观察者添加到列表中。
}
@Override
public void removeObserver(Observer o) { //重写移除方法
this.observers.remove(o); //将观察者从List中移除
}
@Override
public void notifyObservers() { //通知观察者方法
//遍历观察者列表,调用观察者的update方法更新温度数据
for(int i=0;i<this.observers.size();i++) {
this.observers.get(i).update(temperature);
}
}
public void whetherChange() { //温度改变后,调用通知观察者方法。
this.notifyObservers();
}
public float getTemperature() { //得到温度。
return temperature;
}
public void setTemperature(float temperature) {//设置温度,设置后,调用通知观察者方法。
this.temperature=temperature;
notifyObservers();
}
}
WhetherDisplay1 类实现了Observer接口
public class WhetherDisplay1 implements Observer {
private float temprature; //温度属性
public WhetherDisplay1(Subject whether) {//构造方法需要传入一个被观察对象。
whether.registerObserver(this);//调用被观察对象的注册方法,将自身注册。
}
@Override //重写更新温度方法
public void update(float temp) {
this.temprature=temp;
display();
}
public void display() { //输出温度方法,将观察到的温度输出。
System.out.println("display1:"+this.temprature);
}
}
WhetherDisplay2 与WhetherDisplay1类似,这里不再说明。
模拟观察者模式的3个要点:
1.需要两个接口,观察者,和被观察者。
2.被观察者接口需要有两个方法, 一个是注册观察者方法,一个是通知观察者方法。
3.被观察者需要有一个集合,用于储存观察者,注册方法就是向集合里添加对象。通知方法就是遍历集合。
uml图: