基本概念
官方解释:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖的对象能够得到通知并自动更新。
观察者模式是关于一个对象想知道另一个对象中数据变化情况的一种成熟的模式。观察者模式中存在“主题”和若干个“观察者”,把“主题”中变化的东西抽离出来,当发生变化时,所有的“观察者”能够得到通知。
应用场景
很多消息中间件是采用这种观察者模式,Java并发编程中异步回调的方式也类似于观察者模式。
角色分析
- 主题:主题是一个接口,该接口规定了具体主题需要实现的方法;
- 观察者:观察者是一个接口,该接口规定了具体观察者用来更新数据的方法;
- 具体主题:具体主题是实现主题接口的一个实例;
-
具体观察者:是实现观察者接口的一个实例;
观察者模式的UML类图:
观察者模式
代码实现
以下是一个简单的求职者订阅工作中心的观察者模式,观察者通过notify给订阅了信息的求职者发送信息。
Subject
public interface Subject {
void addObserve(Observer observer);
void deleteObserver(Observer observer);
void notifyObserver();
}
SeekJobCenter
public class SeekJobCenter implements Subject {
private String mess;
private boolean changed;
private ArrayList<Observer> personList;
public SeekJobCenter(){
this.personList = new ArrayList<Observer>();
this.mess = "";
this.changed = false;
}
@Override
public void addObserve(Observer observer) {
if(!personList.contains(observer)){
personList.add(observer);
}
}
@Override
public void deleteObserver(Observer observer) {
if(!personList.contains(observer)){
personList.remove(observer);
}
}
@Override
public void notifyObserver() {
if(changed){
for(int i=0;i<personList.size();i++){
Observer observer = personList.get(i);
observer.hearTelephone(mess);
}
}
changed = false;
}
public void giveMessage(String str){
if(str.equals(mess)){
changed = false;
}else{
mess = str;
changed = true;
}
}
}
Observe
public interface Observer {
public void hearTelephone(String heardMess);
}
UniversityStudent
public class UniversityStudent implements Observer {
private Subject subject;
private File myFile;
public UniversityStudent(Subject subject, String fileName){
this.subject = subject;
subject.addObserve(this);
this.myFile = new File(fileName);
}
@Override
public void hearTelephone(String heardMess) {
try{
RandomAccessFile out = new RandomAccessFile(myFile, "rw");
out.seek(out.length());
byte[] b = heardMess.getBytes();
out.write(b);
System.out.println("张三向文件中"+myFile.getName()+"写入如下内容:");
System.out.println(heardMess);
}catch (IOException exp){
System.out.println(exp.toString());
}
}
}
观察者模式的推拉消息
-
推消息模式
主题在发生变化的时候将全部数据推送给具体的观察者,观察者根据消息作出相应的选择。上述方法就是典型的推数据方法。 -
拉消息模式
观察者根据主题提供的获取信息的接口,观察者在得到主题变化的通知之后,自己去拉数据过来,订阅自己需要的内容,参考代码给出了一种拉数据的方法,可以自行查看。
模式优缺点分析
- 具体主题和观察者是松耦合的关系,主题仅仅通过接口依赖于观察者的接口,而不用关心里面的具体的实现类,反之亦然
- 观察者模式满足开闭原则,如果增加新的实现观察者的接口,不用修改具体的主题。
网友评论