来自一位@IT-Coder
观察者模式:
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
打个小比喻:有一栋乌烟瘴气的屋里,有人在聚众XX、有人开房XX、有人XX,他们担心警察来逮了他们。所以得有一个人放哨,这一位就是观察者。而做坏事的就是被观察者。
其实我更想把该模式称为通知者与被通知者。警察要来时,通知者立马通知各位,然后被通知者可以做出相应的响应
//这里直接帖出通知者的基类,请注意看注释
public class Observable {
/**
* 用一个列表,来收容要被通知的恶棍们
* 其实我可以收他们些钱,每人100元
*/
private List<Observer> observers;
/**
* 该变量可以控制下是否真的要通知
* 如果有一点风吹草动就打扰他们干坏事
* 那会很惨的
*/
private boolean changed;
public Observable() {
observers = new ArrayList<Observer>();
}
/**
* 坏蛋给了我钱,我就把他加入到通知队列里面
*/
public void addObserver(Observer o) {
observers.add(o);
}
/**
* 他不想被通知了
*/
public void removeObserver(Observer o) {
observers.remove(o);
}
//确实是要通知了
protected void setChanged() {
changed = true;
}
/**
* obj 要通知他们的数据内容。比如:警察相距100米
* 该方法就一个一个恶棍的通知过去。其实就是调用他们
* 预先设定好的后路,做出相应的响应
*/
public void notifyObservers(Object obj) {
if(changed) {
for(Observer o : observers) {
o.update(this, obj);
}
changed = false;
}
}
public void notifyObservers() {
notifyObservers(null);
}
}
//这是一位真正的通知者,职业的
public class Worker extends Observable{
/**
* 条子是不是真的来了
*/
private boolean bossCome;
/**
* 妈的,真的来了
*/
public void setStatus(boolean bossCome) {
this.bossCome = bossCome;
//通知!
statusChanged();
}
/**
* 调用基类Observable 的通知方法
* 快!
*/
public void statusChanged() {
setChanged();
notifyObservers();
}
//省略其它方法
}
//这是被通知者的接口
//所有要被通知的都要定义好自己的后路
//也就是做出UPDATE
public interface Observer {
/**
* 把通知者做为参数传入
* 知道是谁通知了你,而做出正确的响应
*/
public void update(Observable obserable, Object obj);
}
//这是一个被通知者
public class Gambler implements Observer{
private boolean bossCome;
@Override
public void update(Observable obserable, Object obj) {
if(obserable instanceof Worker) {
Worker worker = (Worker)obserable;
this.bossCome = worker.isBossCome();
}
work();
}
//当事情发生时,要采取的措施
private void work() {
if(bossCome) {
System.out.println("Runngin");
}else {
System.out.println("go on gambling");
}
}
}
运行结果:
public static void main(String[] args) {
Worker worker = new Worker(); //请了一个看场子的
Gambler coder = new Gambler(); //这是个赌徒
worker.addObserver(coder); //让看场子的帮看着警察
worker.setStatus(true); //条子来了,输出:Running
worker.setStatus(false); //条子跑了,输出:go on gambling
}