需求:每当有数据变更需要通知所有的观察者更新数据,在这个需求中,数据的变更内容和观察者接收到通知的“动作”都是被具体实现的,在接口中只定义通知;
角色:观察者,主题,具体观察者,具体主题
主题:
//在主题中只定义对观察者的操作
public interface Subject {
public void addObserver(Observer o);
public void deleteObserver(Observer o);
public void notifyObservers();
}
观察者:
//在观察者中只定义观察者知道数据更新后的操作
public interface Observer {
public void hearTelephone(String hearMess);
}
具体主题:
public class SeekJobCenter implements Subject{
String mess;
boolean changed;
ArrayList<Observer> personList;
SeekJobCenter(){
personList = new ArrayList<Observer>();
mess = "";
changed = false;
}
@Override
public void addObserver(Observer o) {
// TODO Auto-generated method stub
if(!personList.contains(o)){
personList.add(o);
}
}
@Override
public void deleteObserver(Observer o) {
// TODO Auto-generated method stub
if(personList.contains(o)){
personList.remove(o);
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
if(changed){
for(int i = 0;i<personList.size();i++){
Observer observer = personList.get(i);
observer.hearTelephone(mess);
}
changed = false;
}
}
public void giveNewMess(String str){
if(str.equals(mess)){
changed = false;
return;
}
mess = str;
changed = true;
}
}
具体主题中定义了观察者列表,继承并实现了对观察者操作方法的逻辑,并对数据是否更新进行判断;
具体观察者:
public class UniversityStudent implements Observer{
Subject subject;
File myFile;
UniversityStudent(Subject subject, String fileName){
this.subject = subject;
//具体观察者传给具体主题
subject.addObserver(this);
myFile = new File(fileName);
}
@Override
//观察者接听电话具体实现的方法逻辑
public void hearTelephone(String hearMess) {
// TODO Auto-generated method stub
try{
RandomAccessFile out = new RandomAccessFile(myFile, "rw");
out.seek(out.length());
byte[] b = hearMess.getBytes();
out.write(b);
System.out.println("我是一个大学生,我向文件" + myFile.getName() + "写入" + hearMess);
}
catch(IOException ex){
System.out.println(ex.toString());
}
}
}
在具体观察者的构造方法中将自己本身传给了主题的addObserver方法,这样就实现了将具体的观察者add进主题->主题将具体观察者add进具体主题里的观察者list(大概是这么一个过程),后面的hearTelephone方法就是观察者获得“数据更新”的信息后要做的事情
应用:
public static void main(String args[]){
//具体主题
SeekJobCenter subject = new SeekJobCenter();
//具体观察者
UniversityStudent zhang = new UniversityStudent(subject, "a.txt");
subject.giveNewMess("普析需要1个员工");
subject.notifyObservers();
subject.giveNewMess("普析需要1个员工");
subject.deleteObserver(zhang);
subject.giveNewMess("百度需要8个员工");
subject.notifyObservers();
}
在具体主题中增/删观察者,并将信息传给具体主题,具体主题判断此信息是否存在更新(changed是true/false),然后决定是否通知观察者