观察者模式——定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
观察者模式是说,当一个对象的状态发生改变的时候,关心这个对象的所有对象都会接到通知,并作出相应的反应。比如,公司的OA系统提供了消息订阅功能,当有新的消息产生时,所有订阅了该消息的员工都会接到通知,这就是观察者模式。
观察者模式的核心是一个主题接口,一个观察者接口,任何实现了主题接口的实现类都可以被观察者订阅(如会议通知、项目动态都可以被员工订阅),任何实现了观察者接口的实现类都可以订阅、或取消订阅一个主题(如中层员工订阅了会议通知、基础员工订阅了项目动态)。
主题接口:
public interface Subject {
//注册一个观察者
public void registerObserver(Observer o);
//移除一个观察者
public void removeObserver(Observer o);
//通知所有观察者
public void notifyObservers();
}
观察者接口:
public interface Observer {
//观察者作出反应
public void update();
}
一个消息主题(主题接口的实现类),主题记录了所有的观察者列表和主题的状态,当主题的状态发生改变时,可以通知所有订阅者做出相应的反应:
import java.util.ArrayList;
public class MsgSubject implements Subject {
private ArrayList<Observer> observers;//观察者列表
private String msg;//消息(状态)
public MsgSubject(){
this.observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObservers() {
for (Observer o : this.observers) {
o.update();
}
}
//获取主题状态的方法
public String getMsg() {
return msg;
}
//设置主题状态的方法
public void setMsg(String msg) {
this.msg = msg;
}
}
观察者1:
public class Observer1 implements Observer {
private MsgSubject msgSubject;//记录主题的引用,当主题状态发生变化时,可向主题获取状态信息
public Observer1(MsgSubject msgSubject){
this.msgSubject = msgSubject;
msgSubject.registerObserver(this);//向主题注册此观察者
}
@Override
public void update() {
System.out.println("Observer1收到通知:" + this.msgSubject.getMsg());
}
}
观察者2:
public class Observer2 implements Observer {
private MsgSubject msgSubject;//记录主题的引用,当主题状态发生变化时,可向主题获取状态信息
public Observer2(MsgSubject msgSubject){
this.msgSubject = msgSubject;
msgSubject.registerObserver(this);//向主题注册此观察者
}
@Override
public void update() {
System.out.println("Observer2收到通知:" + this.msgSubject.getMsg());
}
}
测试类:
public class Test {
/**
* 观察者模式——定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
*
* 主题接口的实现类记录了所有的观察者列表和主题的状态,可以向一个主题注册或取消注册一个观察者,
* 当主题的状态发生改变时,可以通知所有订阅者做出相应的反应
* @param args
*/
public static void main(String[] args) {
MsgSubject msgSubject = new MsgSubject();
Observer1 o1 = new Observer1(msgSubject);
Observer2 o2 = new Observer2(msgSubject);
msgSubject.setMsg("第一条消息");//改变主题状态
msgSubject.notifyObservers();//通知所有观察者作出反应
msgSubject.setMsg("第二条消息");//改变主题状态
msgSubject.notifyObservers();//通知所有观察者作出反应
msgSubject.removeObserver(o1);//观察者1取消订阅
msgSubject.setMsg("第三条消息");//改变主题状态
msgSubject.notifyObservers();//通知所有观察者作出反应
}
}