问题描述:
当一个对象的状态发生变化时,如何让依赖于它的所有对象都得到通知,并做相应处理呢?
目标对象(Subject、Observable):观察者(Observer) 1:N (一对多的关系)。
目标对象维护一份观察者名单,当自身状态发生变化时,通知名单中的观察者,并做相应处理。
示例代码:
public class Observer_Model {
public static void main(String[] args) {
NewsPaper paper = new NewsPaper();
Reader r1 = new Reader("r1");
Reader r2 = new Reader("r2");
Reader r3 = new Reader("r3");
paper.attach(r3);
paper.attach(r2);
paper.attach(r1);
paper.setContent("China Weekly");
}
}
class Subject {
List<Observer> observerList = new ArrayList<Observer>();
protected void attach(Observer observer){
observerList.add(observer);
}
protected void detach(Observer observer) {
observerList.remove(observer);
}
protected void notifyAllObserver() {
for(Observer observer : observerList){
observer.update(this);
}
}
}
class NewsPaper extends Subject{
String content;
public String getContent(){
return content;
}
public void setContent(String content){
this.content = content;
notifyAllObserver();
}
}
interface Observer{
public void update(Subject s);
}
class Reader implements Observer{
private String name;
public Reader(String name){
this.name = name;
}
@Override
public void update(Subject s) {
System.out.println(name+" have received "+((NewsPaper)s).getContent());
}
}
结果:
r3 have received China Weekly
r2 have received China Weekly
r1 have received China Weekly
2种模型:
推模型:将观察者需要的信息直接传过去,相当于广播信息。
拉模型:观察者需要什么信息自己去找目标对象取。这种模型下,一般会把目标对象本身传给观察者。
jdk 已经实现了目标和观察者的基类和接口:Observable、Observer。
public class Observer_Model2 {
public static void main(String[] args) {
NewsPaper_Java paper = new NewsPaper_Java();
Reader_Java r1 = new Reader_Java("r1");
Reader_Java r2 = new Reader_Java("r2");
Reader_Java r3 = new Reader_Java("r3");
paper.addObserver(r1);
paper.addObserver(r2);
paper.addObserver(r3);
paper.setContent("Beijinger");
}
}
class NewsPaper_Java extends Observable{
String content;
public String getContent(){
return content;
}
public void setContent(String content){
this.content = content;
setChanged(); //注意当内容变化了,要先调用这个方法。
notifyObservers();//相对于 notifyObservers(null),此时会把当前对象传递给观察者
notifyObservers(content);
}
}
class Reader_Java implements java.util.Observer{
private String name;
public Reader_Java(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) { //o 即目标对象,arg是notifyObservers(Object arg) 中的参数
System.out.println(name+" have received "+((NewsPaper_Java)o).getContent());
}
}
可以在目标类即Observable类中,根据不同状态通知不同的观察者。