要点:
观察者模式定义了对象之间一对多的关系。
主题(也可以是观察者)用同一共同接口来更新观察者
被观察者和观察者之间用松耦合方式结合,被观察者不知道观察者的细节,只知道观察者实现了观察者接口。
使用此模式时,你可以从被观察者处推或者拉数据(然而,推的方式被认为更”正确“)
有多个观察者时,不可以依赖特定的通知次序。
Java有多中观察者模式的实现,包括了通用的Java.util
我通过火车速度,火车驾驶员以及乘客的例子来运用观察者模式。
当火车速度改变时,我们需要告知火车驾驶员以及乘客。所以在这里火车速度是被观察者,而火车驾驶员乘客属于观察者。
我在这里定义了一个被观察者接口。
public interface Subject {
//用于观察者来注册
public void registerObserver(Observer o);
//用于观察者解除绑定
public void removeObserver(Observer o);
//用于通知所有观察者
public void notifyObservers();
}
然后定义了一个观察者接口。
public interface Observer {
//用于接收被观察者的数据更新
public void update(int speed);
}
然后让火车速度实现被观察者接口,让火车驾驶员和乘客实现观察者接口。
public class SpeedData implements Subject{
//用于储存所有的观察者
private ArrayList observers;
private int speed;
public SpeedData(){
observers = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
// TODO Auto-generated method stub
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
// TODO Auto-generated method stub
int i = observers.indexOf(o);
if(i >=0 ){
observers.remove(i);
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
for(int i=0; i< observers.size(); i++){
Observer oberver = (Observer) observers.get(i);
oberver.update(speed);
}
}
public void SpeedChanged(){
notifyObservers();
}
public void setSpeed(int speed){
this.speed = speed;
SpeedChanged();
}
}
public class Traindriver implements Observer{
public int length = 100;
public SpeedData speedData;
public Traindriver(SpeedData speedData){
this.speedData = speedData;
speedData.registerObserver(this);
}
@Override
public void update(int speed) {
// TODO Auto-generated method stub
int time = length/speed;
System.out.println("火车驾驶员:火车还有"+time+"分钟到站");
}
}
public class Passenger implements Observer{
public int oldspeed;
public SpeedData speedData;
public Passenger(SpeedData speedData){
//半成年主题的实例,并将观察者注册到主题
this.speedData = speedData;
speedData.registerObserver(this);
}
@Override
public void update(int speed) {
// TODO Auto-generated method stub
if(speed>oldspeed)
System.out.println("乘客:火车变快了,我可以快点回家了");
else
System.out.println("乘客:火车变慢了,我要晚点才能到家了");
oldspeed = speed;
}
}
public class Test {
public static void main(String[] args)
{
SpeedData speedData = new SpeedData();
Traindriver traindriver = new Traindriver(speedData);
Passenger passenger = new Passenger(speedData);
speedData.setSpeed(10);
speedData.setSpeed(20);
speedData.setSpeed(5);
//乘客说我好烦,速度变慢了,我不想知道速度了。所以取消绑定 Passenger
speedData.removeObserver(passenger);
speedData.setSpeed(12);
}
/*
out~
火车驾驶员:火车还有10分钟到站
乘客:火车变快了,我可以快点回家了
火车驾驶员:火车还有5分钟到站
乘客:火车变快了,我可以快点回家了
火车驾驶员:火车还有20分钟到站
乘客:火车变慢了,我要晚点才能到家了
火车驾驶员:火车还有8分钟到站
*/
}
出版者+订阅者 = 观察者模式,在这里火车速度为出版者,而火车驾驶员和乘客属于订阅者。