我所了解的觀察者模式,就是當一個對象發生改變時,可以讓起其的對象接收到資訊并作出回應。
按照我的粗陋經驗來講,比如Android應用打開多個界面時,當我們在某個界面按退出按鈕,就得讓其他所有的界面都結束,即執行.finish()方法。這個以通過維護一個全局的由活動的頁面(Activity)的引用組成的清單來實作。當程式退出時,此清單挨個執行所有引用的.finish()方法,當然也可以用Android的程序棧來實作,與本題無關不另說。再比如做繪圖程式,當界面的某些資料元素發生改變時,也應通知界面元素執行.repaint(),方法,諸如此類,不勝枚舉。
觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀态上發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
我整理了一下,可以讓自己或其他初學者了解開發者的通行做法。
①簡單例子
兩個接口
public interface Observer {
public void update();
}
public interface Subject {
public void attach(Observer o);
public void detach(Observer o);
public void notice();
}
兩個繼承他們的類
public class Student implements Observer {
private String name;
private String phone;
private Teacher teacher;
public Student(String name,Teacher t){
this.name = name;
teacher = t;
}
public void show(){
System.out.println("Name:"+name+"\nTeacher'sphone:"+phone);
}
@Override
public void update() {
phone = teacher.getPhone();
}
}
public class Teacher implements Subject {
private String phone;
private Vector students;
public Teacher() {
phone = "";
students = new Vector();
}
@Override
public void attach(Observer o) {
students.add(o);
}
@Override
public void detach(Observer o) {
students.remove(o);
}
@Override
public void notice() {
for (int i = 0; i < students.size(); i++)
((Observer) students.get(i)).update();
}
public void setPhone(String phone) {
this.phone = phone;
notice();
}
public String getPhone() {
return phone;
}
}
驗證類:
public static void main(String[] args) {
Vector<Student> students = new Vector<Student>();
Teacher t = new Teacher();
for(int i= 0 ;i<10;i++){
Student st = new Student("lili"+i,t);
students.add(st);
t.attach(st);
}
t.setPhone("110");
for(int i=0;i<10;i++)
students.get(i).show();
t.setPhone("10086");
for(int i=0;i<10;i++)
students.get(i).show();
}
}
運作結果:
Name:lili0
Teacher'sphone:110
Name:lili1
Teacher'sphone:110
Name:lili2
Teacher'sphone:110
Name:lili3
Teacher'sphone:110
Name:lili4
Teacher'sphone:110
Name:lili5
Teacher'sphone:110
Name:lili6
Teacher'sphone:110
Name:lili7
Teacher'sphone:110
Name:lili8
Teacher'sphone:110
Name:lili9
Teacher'sphone:110
Name:lili0
Teacher'sphone:10086
Name:lili1
Teacher'sphone:10086
Name:lili2
Teacher'sphone:10086
Name:lili3
Teacher'sphone:10086
Name:lili4
Teacher'sphone:10086
Name:lili5
Teacher'sphone:10086
Name:lili6
Teacher'sphone:10086
Name:lili7
Teacher'sphone:10086
Name:lili8
Teacher'sphone:10086
Name:lili9
Teacher'sphone:10086
②用到Java的API
兩個類:
public class Watched extends Observable {
private String data = "";
public String retrieveData() {
return data;
}
public void changeData(String data) {
if (!this.data.equals(data)) {
this.data = data;
setChanged();
}
notifyObservers();
}
}
public class Watcher implements Observer {
public Watcher(Watched w)
{
w.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("Data has been changed to: '" + ((Watched)o).retrieveData() + "'---args=="+arg);
}
}
驗證:
public class Tester {
static private Watched watched;
static private Observer watcher;
public static void main(String[] args) {
watched = new Watched();
watcher = new Watcher(watched);
watched.changeData("In C, we create bugs.");
watched.changeData("In Java, we inherit bugs.");
watched.changeData("In Java, we inherit bugs.");
watched.changeData("In Visual Basic, we visualize bugs.");
}
}
結果:
Data has been changed to: 'In C, we create bugs.'---args==null
Data has been changed to: 'In Java, we inherit bugs.'---args==null
Data has been changed to: 'In Visual Basic, we visualize bugs.'---args==null