场景:
– 聊天室程序的创建。服务器创建好后,A,B,C三个客户端连上来公开聊
天。A向服务器发送数据,服务器端聊天数据改变。我们希望将这些聊
天数据分别发给其他在线的客户。也就是说,每个客户端需要更新服
务器端得数据。
– 网站上,很多人订阅了”java主题”的新闻。当有这个主题新闻时,就
会将这些新闻发给所有订阅的人。
– 大家一起玩CS游戏时,服务器需要将每个人的方位变化发给所有的客
户。
上面这些场景,我们都可以使用观察者模式来处理。我们
可以把多个订阅者、客户称之为观察者; 需要同步给多个订阅
者的数据封装到对象中,称之为目标。
核心:目标Subject 和 Objservable 发生变化时 告知观察者对象Observer
package com.xiaoqiang.gof23.actionnModel.observer;
import java.util.ArrayList;
import java.util.List;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class Subject {
protected List<Observer> list = new ArrayList<>();
public void registerObserver(Observer obs) {
list.add(obs);
}
public void removeObserver(Observer obs) {
list.remove(obs);
}
//通知所有的观察者更新
public void notifyAllObserver() {
for (Observer obs : list) {
obs.update(this);
}
}
}
package com.xiaoqiang.gof23.actionnModel.observer;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class ConcreteSubject extends Subject {
private int state;
public int getState() {
return state;
}
// 状态发生变化了,通知所有观察者
public void setState(int state) {
this.state = state;
this.notifyAllObserver();
}
}
观察者
package com.xiaoqiang.gof23.actionnModel.observer;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public interface Observer {
void update(Subject subject);
}
package com.xiaoqiang.gof23.actionnModel.observer;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class ObserverA implements Observer {
private int myState;//我的状态
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
@Override
public void update(Subject subject) {
myState = ((ConcreteSubject) subject).getState();
}
}
package com.xiaoqiang.gof23.actionnModel.observer;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class Client {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
// 多个观察者
ObserverA o1 = new ObserverA();
ObserverA o2 = new ObserverA();
ObserverA o3 = new ObserverA();
// 让这三个观察者 添加到观察者队伍中
concreteSubject.registerObserver(o1);
concreteSubject.registerObserver(o2);
concreteSubject.registerObserver(o3);
// 改变subject 的状态
concreteSubject.setState(300);
System.out.println(o1.getMyState());
System.out.println(o2.getMyState());
System.out.println(o3.getMyState());
}
}