观察者模式的本质:触发联动
当一个对象的状态发生改变的时候,如何让依赖它的所有对象得到通知,并进行相应的处理呢?
观察者模式的定义:定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
import java.util.ArrayList;
import java.util.List;
/**
*
* 目标对象,它知道观察它的观察者,并提供注册和删除观察者的接口
*
*/
public class Subject {
/**
* 用来保存注册的观察者对象
*/
private List<Observer> observers = new ArrayList<Observer>();
/**
* 注册观察者对象
* @param observer观察者对象
*/
public void attach(Observer observer){
observers.add(observer);
}
/**
* 删除观察者对象
* @param observer观察者对象
*/
public void detach(Observer observer){
observers.remove(observer);
}
/**
* 通知所有注册的观察者对象
*/
protected void notifyObservers(){
for(Observer observer:observers){
observer.update(this);
}
}
}
/**
*
* 具体的目标对象,负责把有关的状态存入到相应的观察者对象
* 并在自己状态发生变化时,通知各个观察者
*
*/
public class NewsPaper extends Subject{
/**
* 报纸的具体内容
*/
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//状态发生了改变,通知各个观察者
this.notifyObservers();
}
}
/**
*
* 观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象
*
*/
public interface Observer {
/**
* 更新的接口
* @param subject 传入目标对象,方便获取相应的目标对象的状态
*/
public void update(Subject subject);
}
/**
*
* 具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一致
*
*/
public class Reader implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 示意,观察者的状态
*/
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public void update(Subject subject) {
//具体的跟新实现
//这里可能需要更新观察者的状态,使其与目标的状态保持一致
content =((NewsPaper)subject).getContent();
System.out.println(this.getName() + "收到报纸了,内容是" + this.getContent());
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Reader observer1 = new Reader();
observer1.setName("订阅者1");
Reader observer2 = new Reader();
observer2.setName("订阅者2");
Reader observer3 = new Reader();
observer3.setName("订阅者3");
NewsPaper subject = new NewsPaper();
subject.attach(observer1);
subject.attach(observer2);
subject.attach(observer3);
subject.setContent("SHIXIN747");
}
}
Java中的观察者模式:
import java.util.Observable;
/**
*
* 具体的目标对象,负责把有关的状态存入到相应的观察者对象
* 并在自己状态发生变化时,通知各个观察者
*
*/
public class NewsPaper extends Observable{
/**
* 报纸的具体内容
*/
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//状态发生了改变,通知各个观察者
this.setChanged();
//这里是推的方式
this.notifyObservers(this.content);
//这里是拉的方式
this.notifyObservers();
}
}
import java.util.Observable;
import java.util.Observer;
/**
*
* 具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一致
*
*/
public class Reader implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 示意,观察者的状态
*/
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public void update(Observable o, Object arg) {
//这里是获取推的数据
content = arg.toString();
System.out.println(this.getName() + "收到报纸了,内容是" + this.getContent());
//这里是获取拉的数据
content =((NewsPaper)o).getContent();
System.out.println(this.getName() + "收到报纸了,内容是" + this.getContent());
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Reader observer1 = new Reader();
observer1.setName("订阅者1");
Reader observer2 = new Reader();
observer2.setName("订阅者2");
Reader observer3 = new Reader();
observer3.setName("订阅者3");
NewsPaper newsPaper = new NewsPaper();
newsPaper.addObserver(observer1);
newsPaper.addObserver(observer2);
newsPaper.addObserver(observer3);
newsPaper.setContent("SHIXIN747");
}
}