初探設計模式——觀察者模式

我將初次學習設計模式的一些思維活動記錄如下,如有謬論請不吝斧正。

觀察者模式

定義對象之間的一對多的依賴關係,當一個對象改變狀態,它的依賴者都會收到通知並自動更新
出版社是主題對象,讀者們是依賴者對象。一旦出版者改變狀態有了新刊,訂閱者們就會 收到通知並更新自己的狀態。
這就產生了依賴關係。突然一天訂閱者A要退刊,他就不再是出版社的依賴者,自然不會再接受出版社的通知。

實現:包含Subject和Observer接口的類設計
建立接口(面向接口編程)

public interface Subject{
	public void reqisterObserver(Observer o); //註冊觀察者對象
	public void removeObserver(Observer o);		//刪除觀察者對象
	public void notifyObservers();			//主題狀態改變時通知觀察類
}

public interface Observer{
	public void update(狀態作爲參數); //當狀態改變時,主題把這些狀態當作參數傳進來通知觀察者
}
public interface Things{	//封裝觀察者變化的行爲,面向接口編程
	public void doThing();
}

建立主題類並實現主題接口

public class Publisher implements Subject{
	private ArrayLiat observers;		//記錄觀察者
	private String name1;
	private String name2;
	public Publisher{
		observers=new ArrayList();	//構造時建立
	}
//實現主題接口
	public void reqisterObserver(Observer o){
		observers.add(o)//面向接口編程
	}
	public void removeObserver(Observer o){
		int i=obsrvers.indexOf(o);
		if(i>0)
			observers.remove(i);
	}		
	public void notifyObservers(){	
		for(int i=0;i<observers.size();i++){
			Observers observer=(Observer)observers.get(i);	//獲取觀察者對象
			observer.update(name1,name2);		//狀態做參數
		}
	}
//當狀態是否改變,是的話調用notifyObverservers();
	public void nameChanged(){
		if(...)
			notifyObservers();
	}

//獲取狀態,並
	public void setMeasurements(String name1,String name2){
		this.name1=name1;
		this.name1=name2;
		nameChanged();
	}
	
}


建立觀察者類

public class reader implements Observer,Things{
	private String name1;
	private Subject p; 
//每次初始化對象在主題對象中註冊
	public reader(Subject p){
		this.p=p;
		p.refisterObverser(this);		//面向接口編程
	}
//當update在主題中被調用時,把需要的狀態保存下來,並執行相關處理
	public void update(String name1,String name2){
		this.name1=name1;
		doThing();
	}
//這個觀察者類的行爲
	public void doThing(){}
}
**總結**

變化的是主題的狀態、觀察者的數目類型,利用兩接口封裝了這些變化。
面向接口編程,觀察者利用主題接口註冊,運行時觀察者組合進主題產生了依賴關係。
主題不知道觀察者具體類是誰等其他細節,只知道觀察者實現了Observer接口,
利用接口通知觀察者,可以改變觀察者卻不用改變主題,具有松耦合優點。

松耦合:兩對象之間松耦合,可互相交互,不太清楚彼此的細節

第三個設計原則:爲了交互對象之間的松耦合設計而努力
松耦合的設計可以建立有彈性的OO系統,因爲對象間的互相依賴降到了最低所以能應對變化。

以上,主題主動推送狀態。還可以由觀察者通過主題主動獲取,這樣不用修改更新對每位觀察者的調用,只需要增加get方法。

Java內置的Onserver模式支持以上兩種做法(util)
主題(可觀察者)繼承Observable類,觀察者實現Observer接口調用繼承下來的addObserver()
推送狀態:setChanged() 改變標誌,決定是否發送通知(擴展性);notifyservers(Object arg);
接收狀態:update(Observable o,Object arg);

利用java內置實現觀察者主動獲取狀態
觀察者調用所需get方法,setChanged判斷後決定是否發送

public class Publisher extends observable{
	private String name1;
	private String name2;
	public Publisher{
	}
	public void namesChanged(){
		setChanged();
		notifyObservered();
	}
//設置name並判斷是否要傳送狀態
	public void setMeadurements(String name1,String name2){
		this.name1=name1;
		this.name2=name2;
		namesChanged();
	}
//get方法
	public String getName1(){
		return name1;
	}
	public String getName2(){
		return name2;
	}
}
	

public class reader implements Observer,Things{
	Observable observable;
	private String name1;
//構造時將reader註冊成觀察者
	public reader(Observable observable){
		this.observable=observable;
		observable.addObserver(this);
	}
//update方法增加Observable和數據對象作爲參數
	public update(Observable obs,Object arg){
		if(obs instanceof Publisher){
			Publisher publisher=(Publisher)obs;
			this.name1=publisher.getName1();
			doThing();
		}
	}
//reader觀察者對狀態的炒作
	public void doThing(){}
}
Observable類的一些問題:
  • 必須要繼承它,但java又不支持多繼承;
  • 不是接口,無法自己建立實現;
  • setChanged方法被保護,除非繼承否則無法實例組合。

觀察者模式在JDK中有很多應用,以松耦合方式在一系列對象之間溝通狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章