本质:触发联动
简单描述:观察者模式就当目标对象做修改时,广播分发目标对象的状态给所有已注册的观察者,并触发观察者的update方法,每个观察者做各自的处理;
优点:实现了观察者和目标之间的抽象耦合
观察者模式实现了动态联动
观察者模式支持广播通信
缺点:可能会引起无谓的操作
目标对象
Subject
/**
* 目标对象,知道观察他的观察者,并提供注册(添加)和删除观察者的接口
* Created by yangf on 2016/7/27.
*/public class Subject {
//用来保存注册的观察者
List<Observer> observers = new ArrayList<Observer>();
//添加观察者
public void attach(Observer observer){
observers.add(observer);
}
//删除观察者
public void detach(Observer observer){
observers.remove(observer);
}
//通知所有的观察者
protected void notifyObserver(){
for(Observer observer: observers){
observer.update(this);
}
}
}
目标对象实例ConcreteSubject
/**
* Created by yangf on 2016/7/27.
*/
public class ConcreteSubject extends Subject {
//目标对象状态
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
this.notifyObserver();
}
}
观察者接口Observer
具体的观察者对象/**
* 这是一个观察者接口,定义一个更新的接口给那些在目标发生改变时被通知的对象进行更新
* Created by yangf on 2016/7/27.
*/
public interface Observer {
public void update(Subject subject);
}
ConcreteObserver
/**
* 具体的观察者对象,实现更新的方法,使自身的状态和目标状态保持一致
* Created by yangf on 2016/7/27.
*/
public class ConcreteObserver implements Observer {
//观察者的状态
private String observerState;
@Override
public void update(Subject subject) {
observerState = ((ConcreteSubject)subject).getSubjectState();
}
}
以上是拉模型,通过update方法传入目标对象的引用;
还有推模型,是目标对象知道观察者需求的内容,按需求给其推送内容;
观察者模式又被称为发布订阅模式:
命名建议:
(1)目标接口的定义,建议在名称后面跟Subject
(2)观察者接口的定义,建议在名称后面跟Observer
(3)观察者接口的更新方法,建议名称为update,参数的个数及类型不受限制
触发通知的时机,一般确定目标对象的状态更新后分发通知
java中自带的观察者模式
观察者实现
importjava.util.Observable;目标对象实现
import java.util.Observer;
/**
* Created by yangf on 2016/7/27.
*/
public class ConcreteObserver implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(o + name + arg);
}
}
importjava.util.Observable;
/**
* Created by yangf on 2016/7/27.
*/
public class ConcreteSubject extends Observable{
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//必须调用父类的这个方法,在notify中判断这个方法的变量值
this.setChanged();
this.notifyObservers();
this.setChanged();
this.notifyObservers(content);
}
}