观察者模式(Observer pattern)
观察者模式其实在我们的很多应用中都是经常使用到的。那么什么是观察者模式呢?我们先来看一个例子。
比如说,我们在玩CS游戏的时候,加入我的位置状态发生了变化,那么我的状态的变化,就会传给服务器,然后服务器再再我的状态的变化传给所有的游戏玩家。这样的一个过程,其实利用的就是观察者模式。
其中,被观察的对象叫做目标对象(Subject).观察目标对象的叫做观察者(Observer).这是要注意的。可以由很多的观察者观察同一个目标对象。
我们来看一下这个类图:其中Subject表示的是被观察的对象,叫做目标对象。这个类中有几个方法:registerObject():将观察者对象注册到Subject中;removeObserver():将观察者
对象移除观察者队列中。Notify(),当目标对象的状态发生了变化的时候,通知所有的观察者。
Observer类中由一个Update()的方法。就是更新状态,使它与目标对象的状态是同步的。
那么我们如何来实现这个呢?
package com.bjsxt.observer;
import java.util.ArrayList;
import java.util.List;
public class Subject {
protected List<Observer> list = new ArrayList<Observer>();
public void registerObserver(Observer obs){
list.add(obs);
}
public void removeObserver(Observer obs){
list.remove(obs);
}
//通知所有的观察者更新状态
public void notifyAllObservers(){
for (Observer obs : list) {
obs.update(this);
}
}
}
package com.bjsxt.observer;
public class ConcreteSubject extends Subject {
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
//主题对象(目标对象)值发生了变化,请通知所有的观察者
this.notifyAllObservers();
}
}
package com.bjsxt.observer;
public interface Observer {
void update(Subject subject);
}
package com.bjsxt.observer;
public class ObserverA implements Observer {
private int myState; //myState需要跟目标对象的state值保持一致!
@Override
public void update(Subject subject) {
myState = ((ConcreteSubject)subject).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
}
package com.bjsxt.observer;
public class Client {
public static void main(String[] args) {
//目标对象
ConcreteSubject subject = new ConcreteSubject();
//创建多个观察者
ObserverA obs1 = new ObserverA();
ObserverA obs2 = new ObserverA();
ObserverA obs3 = new ObserverA();
//将这三个观察者添加到subject对象的观察者队伍中
subject.registerObserver(obs1);
subject.registerObserver(obs2);
subject.registerObserver(obs3);
//改变subject的状态
subject.setState(3000);
System.out.println("########################");
//我们看看,观察者的状态是不是也发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
//改变subject的状态
subject.setState(30);
System.out.println("########################");
//我们看看,观察者的状态是不是也发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}