国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 微信小程序 微信開發(fā) 用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的實例代碼

用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的實例代碼

Mar 28, 2017 pm 02:20 PM
java 觀察者模式

這篇文章主要介紹了用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的例子,這里Java的微信SDK等部分便不再詳述,只注重關(guān)鍵部分和開發(fā)過程中觀察者模式優(yōu)點的體現(xiàn),需要的朋友可以參考下

還記得警匪片上,匪徒們是怎么配合實施犯罪的嗎?一個團(tuán)伙在進(jìn)行盜竊的時候,總有一兩個人在門口把風(fēng)——如果有什么風(fēng)吹草動,則會立即通知里面的同伙緊急撤退。也許放風(fēng)的人并不一定認(rèn)識里面的每一個同伙;而在里面也許有新來的小弟不認(rèn)識這個放風(fēng)的。但是這沒什么,這個影響不了他們之間的通訊,因為他們之間有早已商定好的暗號。
呵呵,上面提到的放風(fēng)者、偷竊者之間的關(guān)系就是觀察者模式在現(xiàn)實中的活生生的例子。

觀察者(Observer)模式又名發(fā)布-訂閱(Publish/Subscribe)模式。GOF給觀察者模式如下定義:定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。
在這里先講一下面向?qū)ο?/a>設(shè)計的一個重要原則——單一職責(zé)原則。因此系統(tǒng)的每個對象應(yīng)該將重點放在問題域中的離散抽象上。因此理想的情況下,一個對象只做一件事情。這樣在開發(fā)中也就帶來了諸多的好處:提供了重用性和維護(hù)性,也是進(jìn)行重構(gòu)的良好的基礎(chǔ)。
因此幾乎所有的設(shè)計模式都是基于這個基本的
設(shè)計原則來的。觀察者模式的起源我覺得應(yīng)該是在GUI和業(yè)務(wù)數(shù)據(jù)的處理上,因為現(xiàn)在絕大多數(shù)講解觀察者模式的例子都是這一題材。但是觀察者模式的應(yīng)用決不僅限于此一方面。


好了,對于定義的理解總是需要實例來解析的,如今的微信服務(wù)號相當(dāng)火啊,下面就以微信服務(wù)號為背景,給大家介紹觀察者模式。
看一張圖:

用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的實例代碼

其中每個使用者都有上圖中的3條線,為了使圖片清晰省略了。
如上圖所示,服務(wù)號就是我們的主題,使用者就是觀察者。現(xiàn)在我們明確下功能:
1、服務(wù)號就是主題,業(yè)務(wù)就是推送消息
2、觀察者只需要訂閱主題,只要有新的消息就會送來
3、當(dāng)不想要此主題消息時,取消訂閱
4、只要服務(wù)號還在,就會一直有人訂閱
好了,現(xiàn)在我們來看看觀察者模式的類圖:

用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的實例代碼

接下來就是代碼時間了,我們模擬一個微信3D彩票服務(wù)號,和一些訂閱者。
首先開始寫我們的主題接口,和觀察者接口:

package?com.zhy.pattern.observer;?
?
/**?
?*?主題接口,所有的主題必須實現(xiàn)此接口?
?*?
?*?@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?所有的觀察者需要實現(xiàn)此接口?
?*/?
public?interface?Observer?
{?
??public?void?update(String?msg);?
?
}

接下來3D服務(wù)號的實現(xiàn)類:

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?+?"我要告訴舍友們。");?
??}?
???
???
?
}

可以看出:服務(wù)號中維護(hù)了所有向它訂閱消息的使用者,當(dāng)服務(wù)號有新消息時,通知所有的使用者。整個架構(gòu)是一種松耦合,主題的實現(xiàn)不依賴與使用者,當(dāng)增加新的使用者時,主題的代碼不需要改變;使用者如何處理得到的數(shù)據(jù)與主題無關(guān);
最后看下測試代碼:

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的服務(wù)號?
????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"?);?
?????
??}?
}

輸出結(jié)果:

observer1?得到?3D?號碼?-->20140420的3D號碼是:127,?我要記下來。?
observer2?得到?3D?號碼?-->20140420的3D號碼是:127我要告訴舍友們。?
observer1?得到?3D?號碼?-->20140421的3D號碼是:333,?我要記下來。?
observer2?得到?3D?號碼?-->20140421的3D號碼是:333我要告訴舍友們。

對于JDK或者Andorid中都有很多地方實現(xiàn)了觀察者模式,比如XXXView.addXXXListenter , 當(dāng)然了 XXXView.setOnXXXListener不一定是觀察者模式,因為觀察者模式是一種一對多的關(guān)系,對于setXXXListener是1對1的關(guān)系,應(yīng)該叫回調(diào)。

恭喜你學(xué)會了觀察者模式,上面的觀察者模式使我們從無到有的寫出,當(dāng)然了java中已經(jīng)幫我們實現(xiàn)了觀察者模式,借助于java.util.Observable和java.util.Observer。
下面我們使用Java內(nèi)置的類實現(xiàn)觀察者模式:

首先是一個3D彩票服務(wù)號主題:

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();?
??}?
}

下面是一個雙色球的服務(wù)號主題:

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");?
?????
??}?
}

測試結(jié)果:

subjectFor3d's?msg?--?>hello?3d'nums?:?110??
subjectForSSQ's?msg?--?>ssq'nums?:?12,13,31,5,4,3?15

可以看出,使用Java內(nèi)置的類實現(xiàn)觀察者模式,代碼非常簡潔,對了addObserver,removeObserver,notifyObservers都已經(jīng)為我們實現(xiàn)了,所有可以看出Observable(主題)是一個類,而不是一個接口,基本上書上都對于Java的如此設(shè)計抱有反面的態(tài)度,覺得Java內(nèi)置的觀察者模式,違法了面向接口編程這個原則,但是如果轉(zhuǎn)念想一想,的確你拿一個主題在這寫觀察者模式(我們自己的實現(xiàn)),接口的思想很好,但是如果現(xiàn)在繼續(xù)添加很多個主題,每個主題的ddObserver,removeObserver,notifyObservers代碼基本都是相同的吧,接口是無法實現(xiàn)代碼復(fù)用的,而且也沒有辦法使用組合的模式實現(xiàn)這三個方法的復(fù)用,所以我覺得這里把這三個方法在類中實現(xiàn)是合理的。

以上是用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的實例代碼的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務(wù),必須先關(guān)閉自動提交模式,再執(zhí)行多個操作,最后根據(jù)結(jié)果提交或回滾;1.調(diào)用conn.setAutoCommit(false)以開始事務(wù);2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調(diào)用conn.commit(),若發(fā)生異常則調(diào)用conn.rollback()確保數(shù)據(jù)一致性;同時應(yīng)使用try-with-resources管理資源,妥善處理異常并關(guān)閉連接,避免連接泄漏;此外建議使用連接池、設(shè)置保存點實現(xiàn)部分回滾,并保持事務(wù)盡可能短以提升性能。

如何使用Java的日歷? 如何使用Java的日歷? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當(dāng)前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現(xiàn)代Java中日期處理應(yīng)優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

比較Java框架:Spring Boot vs Quarkus vs Micronaut 比較Java框架:Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

了解網(wǎng)絡(luò)端口和防火墻 了解網(wǎng)絡(luò)端口和防火墻 Aug 01, 2025 am 06:40 AM

NetworkPortSandFireWallsworkTogetHertoEnableCommunication whereSeringSecurity.1.NetWorkPortSareVirtualendPointSnumbered0-655 35,with-Well-with-Newonportslike80(HTTP),443(https),22(SSH)和25(smtp)sindiessingspefificservices.2.portsoperateervertcp(可靠,c

垃圾收集如何在Java工作? 垃圾收集如何在Java工作? Aug 02, 2025 pm 01:55 PM

Java的垃圾回收(GC)是自動管理內(nèi)存的機(jī)制,通過回收不可達(dá)對象釋放堆內(nèi)存,減少內(nèi)存泄漏風(fēng)險。1.GC從根對象(如棧變量、活動線程、靜態(tài)字段等)出發(fā)判斷對象可達(dá)性,無法到達(dá)的對象被標(biāo)記為垃圾。2.基于標(biāo)記-清除算法,標(biāo)記所有可達(dá)對象,清除未標(biāo)記對象。3.采用分代收集策略:新生代(Eden、S0、S1)頻繁執(zhí)行MinorGC;老年代執(zhí)行較少但耗時較長的MajorGC;Metaspace存儲類元數(shù)據(jù)。4.JVM提供多種GC器:SerialGC適用于小型應(yīng)用;ParallelGC提升吞吐量;CMS降

比較Java構(gòu)建工具:Maven vs. Gradle 比較Java構(gòu)建工具:Maven vs. Gradle Aug 03, 2025 pm 01:36 PM

Gradleisthebetterchoiceformostnewprojectsduetoitssuperiorflexibility,performance,andmoderntoolingsupport.1.Gradle’sGroovy/KotlinDSLismoreconciseandexpressivethanMaven’sverboseXML.2.GradleoutperformsMaveninbuildspeedwithincrementalcompilation,buildcac

以身作則,解釋說明 以身作則,解釋說明 Aug 02, 2025 am 06:26 AM

defer用于在函數(shù)返回前執(zhí)行指定操作,如清理資源;參數(shù)在defer時立即求值,函數(shù)按后進(jìn)先出(LIFO)順序執(zhí)行;1.多個defer按聲明逆序執(zhí)行;2.常用于文件關(guān)閉等安全清理;3.可修改命名返回值;4.即使發(fā)生panic也會執(zhí)行,適合用于recover;5.避免在循環(huán)中濫用defer,防止資源泄漏;正確使用可提升代碼安全性和可讀性。

使用HTML'輸入類型”作為用戶數(shù)據(jù) 使用HTML'輸入類型”作為用戶數(shù)據(jù) Aug 03, 2025 am 11:07 AM

選擇合適的HTMLinput類型能提升數(shù)據(jù)準(zhǔn)確性、增強(qiáng)用戶體驗并提高可用性。1.根據(jù)數(shù)據(jù)類型選用對應(yīng)input類型,如text、email、tel、number和date,可實現(xiàn)自動校驗和適配鍵盤;2.利用HTML5新增類型如url、color、range和search,可提供更直觀的交互方式;3.配合使用placeholder和required屬性,可提升表單填寫效率和正確率,但需注意placeholder不能替代label。

See all articles