天天看點

Java 簡簡單單了解觀察者模式

我所了解的觀察者模式,就是當一個對象發生改變時,可以讓起其的對象接收到資訊并作出回應。

按照我的粗陋經驗來講,比如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