用Java設計形式中的不雅察者形式開辟微信"號的例子。本站提示廣大學習愛好者:(用Java設計形式中的不雅察者形式開辟微信"號的例子)文章只能為提供參考,不一定能成為您想要的結果。以下是用Java設計形式中的不雅察者形式開辟微信"號的例子正文
還記得警匪片上,強盜們是怎樣合營實行犯法的嗎?一個團伙在停止偷盜的時刻,總有一兩小我在門口把風——假如有甚麼風吹草動,則會立刻告訴外面的同伙緊迫退卻。或許放風的人其實不必定熟悉外面的每個同伙;而在外面或許有新來的小弟不熟悉這個放風的。然則這沒甚麼,這個影響不了他們之間的通信,由於他們之間有早已約定好的記號。
呵呵,下面提到的放風者、偷盜者之間的關系就是不雅察者形式在實際中的活生生的例子。
不雅察者(Observer)形式別名宣布-定閱(Publish/Subscribe)形式。GOF給不雅察者形式以下界說:界說對象間的一種一對多的依附關系,當一個對象的狀況產生轉變時,一切依附於它的對象都獲得告訴並被主動更新。
在這裡先講一上面向對象設計的一個主要准繩——單一職責准繩。是以體系的每一個對象應當將重點放在成績域中的團圓籠統上。是以幻想的情形下,一個對象只做一件工作。如許在開辟中也就帶來了諸多的利益:供給了重用性和保護性,也是停止重構的優越的基本。
是以簡直一切的設計形式都是基於這個根本的設計准繩來的。不雅察者形式的來源我認為應當是在GUI和營業數據的處置上,由於如今絕年夜多半講授不雅察者形式的例子都是這一題材。然則不雅察者形式的運用決不只限於此一方面。
好了,關於界說的懂得老是須要實例來解析的,現在的微佩服務號相當火啊,上面就以微佩服務號為配景,給年夜家引見不雅察者形式。
看一張圖:
個中每一個應用者都有上圖中的3條線,為了使圖片清楚省略了。
如上圖所示,辦事號就是我們的主題,應用者就是不雅察者。如今我們明白下功效:
1、辦事號就是主題,營業就是推送新聞
2、不雅察者只須要定閱主題,只需有新的新聞就會送來
3、當不想要此主題新聞時,撤消定閱
4、只需辦事號還在,就會一向有人定閱
好了,如今我們來看看不雅察者形式的類圖:
接上去就是代碼時光了,我們模仿一個微信3D彩票辦事號,和一些定閱者。
起首開端寫我們的主題接口,和不雅察者接口:
package com.zhy.pattern.observer; /** * 主題接口,一切的主題必需完成此接口 * * @author zhy * */ public interface Subject { /** * 注冊一個不雅察著 * * @param observer */ public void registerObserver(Observer observer); /** * 移除一個不雅察者 * * @param observer */ public void removeObserver(Observer observer); /** * 告訴一切的不雅察著 */ public void notifyObservers(); } package com.zhy.pattern.observer; /** * @author zhy 一切的不雅察者須要完成此接口 */ public interface Observer { public void update(String msg); }
接上去3D辦事號的完成類:
package com.zhy.pattern.observer; import java.util.ArrayList; import java.util.List; public class ObjectFor3D implements Subject { private List<Observer> observers = new ArrayList<Observer>(); /** * 3D彩票的號碼 */ private String msg; @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { int index = observers.indexOf(observer); if (index >= 0) { observers.remove(index); } } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(msg); } } /** * 主題更新新聞 * * @param msg */ public void setMsg(String msg) { this.msg = msg; notifyObservers(); } }
模仿兩個應用者:
package com.zhy.pattern.observer; public class Observer1 implements Observer { private Subject subject; public Observer1(Subject subject) { this.subject = subject; subject.registerObserver(this); } @Override public void update(String msg) { System.out.println("observer1 獲得 3D 號碼 -->" + msg + ", 我要記上去。"); } }
package com.zhy.pattern.observer; public class Observer2 implements Observer { private Subject subject ; public Observer2(Subject subject) { this.subject = subject ; subject.registerObserver(this); } @Override public void update(String msg) { System.out.println("observer2 獲得 3D 號碼 -->" + msg + "我要告知捨友們。"); } }
可以看出:辦事號中保護了一切向它定閱新聞的應用者,當辦事號有新新聞時,告訴一切的應用者。全部架構是一種松耦合,主題的完成不依附與應用者,當增長新的應用者時,主題的代碼不須要轉變;應用者若何處置獲得的數據與主題有關;
最初看下測試代碼:
package com.zhy.pattern.observer.test; import com.zhy.pattern.observer.ObjectFor3D; import com.zhy.pattern.observer.Observer; import com.zhy.pattern.observer.Observer1; import com.zhy.pattern.observer.Observer2; import com.zhy.pattern.observer.Subject; public class Test { public static void main(String[] args) { //模仿一個3D的辦事號 ObjectFor3D subjectFor3d = new ObjectFor3D(); //客戶1 Observer observer1 = new Observer1(subjectFor3d); Observer observer2 = new Observer2(subjectFor3d); subjectFor3d.setMsg("20140420的3D號碼是:127" ); subjectFor3d.setMsg("20140421的3D號碼是:333" ); } }
輸入成果:
observer1 獲得 3D 號碼 -->20140420的3D號碼是:127, 我要記上去。 observer2 獲得 3D 號碼 -->20140420的3D號碼是:127我要告知捨友們。 observer1 獲得 3D 號碼 -->20140421的3D號碼是:333, 我要記上去。 observer2 獲得 3D 號碼 -->20140421的3D號碼是:333我要告知捨友們。
關於JDK或許Andorid中都有許多處所完成了不雅察者形式,好比XXXView.addXXXListenter , 固然了 XXXView.setOnXXXListener紛歧定是不雅察者形式,由於不雅察者形式是一種一對多的關系,關於setXXXListener是1對1的關系,應當叫回調。
祝賀你學會了不雅察者形式,下面的不雅察者形式使我們從無到有的寫出,固然了java中曾經幫我們完成了不雅察者形式,借助於java.util.Observable和java.util.Observer。
上面我們應用Java內置的類完成不雅察者形式:
起首是一個3D彩票辦事號主題:
package com.zhy.pattern.observer.java; import java.util.Observable; public class SubjectFor3d extends Observable { private String msg ; public String getMsg() { return msg; } /** * 主題更新新聞 * * @param msg */ public void setMsg(String msg) { this.msg = msg ; setChanged(); notifyObservers(); } }
上面是一個雙色球的辦事號主題:
package com.zhy.pattern.observer.java; import java.util.Observable; public class SubjectForSSQ extends Observable { private String msg ; public String getMsg() { return msg; } /** * 主題更新新聞 * * @param msg */ public void setMsg(String msg) { this.msg = msg ; setChanged(); notifyObservers(); } }
最初是我們的應用者:
package com.zhy.pattern.observer.java; import java.util.Observable; import java.util.Observer; public class Observer1 implements Observer { public void registerSubject(Observable observable) { observable.addObserver(this); } @Override public void update(Observable o, Object arg) { if (o instanceof SubjectFor3d) { SubjectFor3d subjectFor3d = (SubjectFor3d) o; System.out.println("subjectFor3d's msg -- >" + subjectFor3d.getMsg()); } if (o instanceof SubjectForSSQ) { SubjectForSSQ subjectForSSQ = (SubjectForSSQ) o; System.out.println("subjectForSSQ's msg -- >" + subjectForSSQ.getMsg()); } } }
看一個測試代碼:
package com.zhy.pattern.observer.java; public class Test { public static void main(String[] args) { SubjectFor3d subjectFor3d = new SubjectFor3d() ; SubjectForSSQ subjectForSSQ = new SubjectForSSQ() ; Observer1 observer1 = new Observer1(); observer1.registerSubject(subjectFor3d); observer1.registerSubject(subjectForSSQ); subjectFor3d.setMsg("hello 3d'nums : 110 "); subjectForSSQ.setMsg("ssq'nums : 12,13,31,5,4,3 15"); } }
測試成果:
subjectFor3d's msg -- >hello 3d'nums : 110 subjectForSSQ's msg -- >ssq'nums : 12,13,31,5,4,3 15
可以看出,應用Java內置的類完成不雅察者形式,代碼異常簡練,對了addObserver,removeObserver,notifyObservers都曾經為我們完成了,一切可以看出Observable(主題)是一個類,而不是一個接口,根本上書上都關於Java的如斯設計抱有不和的立場,認為Java內置的不雅察者形式,守法了面向接口編程這個准繩,然則假如轉念想想,切實其實你拿一個主題在這寫不雅察者形式(我們本身的完成),接口的思惟很好,然則假如如今持續添加許多個主題,每一個主題的ddObserver,removeObserver,notifyObservers代碼根本都是雷同的吧,接口是沒法完成代碼復用的,並且也沒有方法應用組合的形式完成這三個辦法的復用,所以我認為這裡把這三個辦法在類中完成是公道的。