观察者模式是对象的行为模式,又叫发布-订阅模式,模型-视图模式,源-监听器模式或从属者模式;观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某个主题对象,当主题对象的状态发生变化时,会主动通知所有观察者,实现状态的动态同步。
使用场景
观察者模式的使用场景其实用一个简单的短语即可说明:发布-订阅;所有细分的观察者模式使用场景都属于该场景的细化,如:
- 需要实现一个多对一的依赖,同时需要在依赖的对象之间实现松耦合;那么此处的多即为订阅者,一即为发布者
- 在业务场景中,某个对象的变更需要通知另外一类对象;那么前一个对象可以看成是发布者,后一类对象可以看成订阅者
观察者模式从实现方式来看可以为两种方式,一种是推模式,一种是拉模式:
- 推模型;在状态发生变更时,由主题对象发起通知,且主题在发生变更后将全部数据交给具体观察者
- 拉模式;在状态发生变更时,还是由主题对象发起通知,但是通知信息较简单,其详细更改信息的获取则由观察者主动请求
一般来说当具体主题认为具体观察者需要这些变化后的全部数据时往往采用推数据方式,但是如果订阅对象较多,且订阅对象对数据的需求各不相同,则一般采取拉模式
代码示例
下面分别就推模式与拉模式分别给出代码示例
- 推模式:
//发布者
public class PushObserverSubject {
private String state ;
private ArrayList<Observer> observerList = new ArrayList<Observer>();
protected void registObserver(Observer o) {
observerList.add(o );
}
protected boolean deleteObserver(Observer o){
return observerList .remove(o );
}
protected void notifyObservers() {
for(Observer theObserver : this.observerList){
theObserver.update(this); //通知观察者时发送全部数据
}
}
protected void stateChange (String state ) {
this.state = state ;
this.notifyObservers();
}
protected String getState() {
return state;
}
}
//观察者抽象类
public abstract class Observer {
public Observer(PushObserverSubject os ){
os.registObserver(this);
}
protected abstract void update(PushObserverSubject os);
}
//观察者具体实现类A
public class ObserverA extends Observer{
public ObserverA(PushObserverSubject os ) {
super(os );
}
@Override
protected void update(PushObserverSubject os) {
System. out.println("ObserverA update ObserverSubject is " + os);
System. out.println("ObserverA state changed: " + os.getState());
}
}
//观察者具体实现类B
public class ObserverB extends Observer{
public ObserverB(PushObserverSubject os ) {
super(os);
}
@Override
protected void update(PushObserverSubject os) {
System. out.println("ObserverB update ObserverSubject is " + os);
System. out.println("ObserverB state changed: " + os.getState());
}
}
//客户端调用
public class ObserverRun {
public static void main(String[] args) {
PushObserverSubject theSubject = new PushObserverSubject();
Observer theObserverA = new ObserverA(theSubject);
Observer theObserverB = new ObserverB(theSubject);
theSubject.stateChange("state_1" );
}
}
运行结果:
ObserverA update ObserverSubject is designpattern.observer.PushObserverSubject@6d6f6e28
ObserverA state changed: state_1
ObserverB update ObserverSubject is designpattern.observer.PushObserverSubject@6d6f6e28
ObserverB state changed: state_1
- 拉模式
//发布者
public class PullObserverSubject {
private String state ;
private ArrayList<Observer> observerList = new ArrayList<Observer>();
protected void registObserver(Observer o) {
observerList.add(o );
}
protected boolean deleteObserver(Observer o){
return observerList .remove(o );
}
protected void notifyObservers() {
for(Observer theObserver : this.observerList){
theObserver.update(); //只通知观察者状态已变更
}
}
protected void stateChange (String state ) {
this.state = state ;
this.notifyObservers();
}
protected String getState() {
return state;
}
}
//观察者抽象类
public abstract class Observer {
protected PullObserverSubject os;
public Observer(PullObserverSubject os){
this.os = os;
os.registObserver(this);
}
protected abstract void update();
}
//观察者具体实现类A
public class ObserverA extends Observer{
public ObserverA(PullObserverSubject os ) {
super(os);
}
@Override
protected void update() {
System. out.println("ObserverA update ObserverSubject is " + os);
System. out.println("ObserverA state changed: " + this.os.getState());
}
}
//观察者具体实现类B
public class ObserverB extends Observer{
public ObserverB(PullObserverSubject os ) {
super(os);
}
@Override
protected void update() {
System. out.println("ObserverB update ObserverSubject is " + os);
System. out.println("ObserverB state changed: " + this.os.getState());
}
}
//客户端调用
public class ObserverRun {
public static void main(String[] args) {
PullObserverSubject theSubject = new PullObserverSubject();
Observer theObserverA = new ObserverA(theSubject);
Observer theObserverB = new ObserverB(theSubject);
theSubject.stateChange("state_1" );
}
}
运行结果:
ObserverA update ObserverSubject is designpattern.observer.PullObserverSubject@6d6f6e28
ObserverA state changed: state_1
ObserverB update ObserverSubject is designpattern.observer.PullObserverSubject@6d6f6e28
ObserverB state changed: state_1
另外,在Java的java.util
库里面,提供了一个Observable
类以及一个Observer
接口,构成Java语言对观察者模式的支持;通过这些接口可以方便快捷的实现Observer模式,简单示例如下:
//发布者,实现Observable接口
public class Watched extends Observable{
private String data = "";
public String getData() {
return data;
}
public void setData(String data) {
if(!this.data.equals(data)){
this.data = data;
setChanged();
}
notifyObservers();
}
}
//观察者,实现Observer接口
public class Watcher implements Observer{
public Watcher(Observable o){
o.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("状态发生改变:" + ((Watched)o).getData());
}
}
//客户端调用
Watched beWatched = new Watched();
Watcher theWatcher = new Watcher(beWatched);
beWatched.setData("new status");
//运行结果
状态发生改变:new status