模式意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。
模式适用性
在许多设计中,经常涉及对个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象的数据变化。
模式参与者
- 主题(subject):主题是一个接口,该接口规定了具体主题需要实现的方法。
- 观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更新数据的方法。
- 具体主题(ConcreteSubject):具体主题是实现主体接口的一个实例,该实例包含有可以经常发生变化的数据。
- 具体观察者(ConcreteObserver):具体观察者是实现观察者接口类的一个实例。
一个实例:
主题(Subject):Subject.java
public interface Subject {
public void addObserver(Observer o);
public void deleteObserver(Observer o);
public void notifyObservers();
}
观察者(Observer):Observer.java
public interface Observer {
public void hearTelephone(String heardMess);
}
具体主题(ConcreteSubject):SeekJobCenter.java
public class SeekJobCenter implements Subject{
String mess;
boolean changed;
ArrayList<Observer> personList;
public SeekJobCenter() {
personList = new ArrayList<>();
mess = "";
changed = false;
}
public void addObserver(Observer o) {
if (!(personList.contains(o))) {
personList.add(o);
}
}
public void deleteObserver(Observer o) {
if (personList.contains(o)) {
personList.remove(o);
}
}
public void notifyObservers() {
if (changed) {
for (int i = 0; i < personList.size(); i++) {
Observer observer = personList.get(i);
observer.hearTelephone(mess);
}
changed = false;
}
}
public void giveNewMess(String string) {
if (string.equals(mess)) {
changed = false;
}else{
mess = string;
changed = true;
}
}
}
具体观察者(ConcreteObserver):UniversityStudent.java
public class UniversityStudent implements Observer{
Subject subject;
File myFile;
public UniversityStudent(Subject subject,String fileName) {
this.subject = subject;
subject.addObserver(this);
myFile = new File(fileName);
}
@Override
public void hearTelephone(String heardMess) {
try {
@SuppressWarnings("resource")
RandomAccessFile out = new RandomAccessFile(myFile, "rw");
out.seek(out.length());
byte[] b = heardMess.getBytes();
out.write(b);
System.out.println("我是一个大学生,");
System.out.println("我向文件" + myFile.getName() + "写入如下内容:");
System.out.println(heardMess);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
优点
- 具体观察者和观察者之间是松耦合关系
- 观察者模式满足“开-闭原则”。主题接口仅仅依赖于观察者接口。