不想當設計模式巨星的程序員不是好設計師。從本期開始我們對設計模式做一個系統(tǒng)性的總結。HeadFirst設計模式看了兩遍。我盡量將書中的每個模式的重點提取出來,方便研讀。
觀察者模式在日常開發(fā)中經(jīng)常用到-比如按鈕的監(jiān)聽、網(wǎng)絡返回數(shù)據(jù)狀態(tài)的監(jiān)聽、文件下載的監(jiān)聽等,都可以用觀察者模式來實現(xiàn)。那么觀察模式到底是怎樣定義的,其中有哪些注意點?我們通過一項例子再來認識觀察者模式:
比如有這樣一個情節(jié)--------訂閱報紙:
1、報社提供的業(yè)務是出版報紙。
2、用戶只要向報社訂閱了報紙,報社在有新報紙出版時,就會將報紙送給用戶。而且用戶一定可以收到新的報紙。
3、當用戶不想看報紙時,取消訂閱,再有新報紙時,報社也不會向用戶推送。
觀察者模式就跟訂閱報紙是一回事,只是名稱不一樣罷了。
圖釋:

定義觀察者模式:定義一個對象和多個依賴。當一個對象改變時,他的所有依賴者都會收到通知,并自動更新。
觀察者模式提供了一種這樣的設計思想。對象和依賴者之間是松耦合。他們依然可以交互,但是不太清楚彼此的細節(jié)。松耦合的設計之所以能讓我們建立有彈性的OO(面向?qū)ο螅┫到y(tǒng),能夠應對變化,是因為他們之間相互依賴的降低。
結合具體代碼做一個簡單的講解。
1、根據(jù)出版社(PRess)和讀者朋友(Reader)兩種角色來設計觀察者模式,根據(jù)上文定義,出版社需要為讀者朋友(Reader)提供三種功能:注冊監(jiān)聽、取消監(jiān)聽、通知更新。讀者朋友需要的技能是Reading。中間還需要一個觀察者接口Observer來鏈接他們的狀態(tài)更新。所以需要設計這樣三個接口:
出版社接口
public interface ipress{ public void registerObserver(Observer o);//注冊觀察者 public void removeObserver(Observer o);//刪除觀察者 public void notifyObservers();//通知更新}閱讀者接口
public interface IReader(){ public void reading();//閱讀者只有一個閱讀功能}觀察者接口public interface IObserver{ public void updata(String date,String content);}2、依據(jù)上面接口,結合實際需求,寫出相應實現(xiàn)。
出版社
public class PressData implements IPress{ private ArrarList observers; private String date; private String content; public PressData(){ observers=new ArrarList<IObserver>(); } @Override public void registerObserver((Observer o){ observers.add(o); } @Override public void removeObserver(IObserver o){ int i=observers.indexOf(o); if(i>=0){ observers.remove(i); } } @Override public void notifyObservers(){ for(int i=0;i<observers.size();i++){ IObserver observer=(IObserver)observers.get(i); observer.updata(date,content); } } public void setNewsData(String date,String content){ this.date=data; this.content=content; notifyObservers; }}閱讀者
public class Reader implements IObserver,IReader{ private String date; private String content; private PressData pressData; public Reader(PressData pressData){ this.pressData=pressData; this.pressData.registerObserver(this); } @Override public void updata(date,content){ this.date; this.content=content; reading(date,content); } @Override public void reading(){ System.out.println("News----"+date+"----"+content); }}3、具體調(diào)用public class ReadingStation(){ public static void main(String[] args){ PressData pressData=new PressData(); Reader reader=new Reader(pressData); pressData.setNewsData("20170220","觀察者模式"); }}這里定義的觀察者模式可能跟我們已經(jīng)用到的不太一樣?;蛟S你會覺得稍微復雜了一點,怎么會這么多類?。。。實際確實如此,這里寫的稍微松耦合了一下。實際我們之前寫的時候一個類就搞定了。那么根據(jù)書中介紹的,再次強調(diào),我們要注重松耦合。當然只定義一個Oberver去掉注冊和取消監(jiān)聽的方法,我們直接實現(xiàn)Oberver類,然后傳入調(diào)用接口行了,這樣的情況也是有的。但是上面的例子確實值得思考。
|
新聞熱點
疑難解答