本人能力有限,若有明顯錯誤,不規範的地方,請指正,謝謝。java
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並自動更新。git
依賴(Dependents)發佈-訂閱(Publish-Subscribe)程序員
在應用觀察者模式時須要考慮一些開發效率和運行效率問題,程序中包括一個被觀察者,多個觀察則,開發和調式等內容會比較複雜。github
Observer模式是直接接觸過的最多見的設計模式之一,GUI程序應用得比較廣。設計模式
開發技術前線網站是一個聚集各類技術文章的網站,它支持郵箱訂閱,一旦有用戶訂閱了它,每當網站出新內容時,會自動將新內容推送到用戶郵箱。網絡
由於java核心庫裏已經有了Observer抽象觀察者接口和Observable抽象被觀察者類,因此咱們直接實現和繼承它們便可擴展咱們本身的業務。異步
/** * 程序員是訂閱者,就是具體的觀察者 * * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/24 0:07 */ public class Coder implements Observer { /** * 名字 */ private String name; public Coder(String name) { this.name = name; } @Override public void update(Observable o, Object arg) { if (arg instanceof Page) { System.out.println(name + " 獲得了文章:" + arg.toString()); } } @Override public String toString() { return "Coder{" + "name='" + name + '\'' + '}'; } } /** * 開發技術網站 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/24 0:16 */ public class DevTechFrontier extends Observable { /** * 通知全部觀察者 * @param page 新的文章 */ public void postNewPage(Page page){ // 設置狀態已改變 setChanged(); notifyObservers(page); } } /** * 文章類 * @author newtrekWang * @email wangjiaxing20160101@gmail.com * @time 2018/8/24 0:08 */ public class Page { private String date; private String author; private String content; public Page(String date, String author, String content) { this.date = date; this.author = author; this.content = content; } @Override public String toString() { return "Page{" + "date='" + date + '\'' + ", author='" + author + '\'' + ", content='" + content + '\'' + '}'; } } // 測試 public static void main(String[] args){ DevTechFrontier devTechFrontier = new DevTechFrontier(); Coder coder1 = new Coder("conder1"); Coder coder2 = new Coder("conder2"); Coder coder3 = new Coder("conder3"); Coder coder4 = new Coder("conder4"); Coder coder5 = new Coder("conder5"); devTechFrontier.addObserver(coder1); devTechFrontier.addObserver(coder2); devTechFrontier.addObserver(coder3); devTechFrontier.addObserver(coder4); devTechFrontier.addObserver(coder5); devTechFrontier.postNewPage(new Page(new Date().toString(),"wang","技術內容")); }
執行結果:mvvm
conder5 獲得了文章:Page{date='Fri Aug 24 00:19:55 CST 2018', author='wang', content='技術內容'} conder4 獲得了文章:Page{date='Fri Aug 24 00:19:55 CST 2018', author='wang', content='技術內容'} conder3 獲得了文章:Page{date='Fri Aug 24 00:19:55 CST 2018', author='wang', content='技術內容'} conder2 獲得了文章:Page{date='Fri Aug 24 00:19:55 CST 2018', author='wang', content='技術內容'} conder1 獲得了文章:Page{date='Fri Aug 24 00:19:55 CST 2018', author='wang', content='技術內容'}
咱們往ListView添加數據後,都會調用Adapterder的notifyDataChanged()方法刷新顯示數據。其實它就是內置了一個DataSetObservable和多個DataSetObserver,調用notifyDataChanged()會讓DataSetObservable一一通知DataSetObserver的onChanged()回調,而後onChanged()會根據如今的數據狀況調用ListView從新佈局方法,刷新UI,這就是一個典型的Observer模式。ide
BroadcastReceiver是Android的四個組件之一,它做爲應用內,進程間的一種重要通訊手段,可以將某個消息經過廣播的形式傳遞給它註冊的對應廣播接收器的對象。接收對象即BroadcastReceiver,爲觀察者,而後它須要經過Context的registerReceiver方法註冊到AMS中,當經過sendBroadcase發送廣播時,全部註冊了對應的IntentFilter的BroadcastReceiver對象就會接收到這個消息,Broadcast的onReceive方法就會調用,這就是一個典型的發佈--訂閱模式,只是發送廣播時會經過IntentFilter做一些匹配過濾操做。函數
在Android開發中,咱們常常須要在兩個不一樣的業務場景之間進行通訊,好比子線程要發消息給主線程。咱們單靠AndroidSDK裏面的API的話,就必須重寫Handler,將主線程中建立的Handler對象傳給子線程,而後子線程經過handler發送消息,主線程維護的消息隊列收到消息,而後消息又交給handler處理,最終完成消息發送。
Android創造的AsyncTask和Handler貌似讓異步代碼作得簡潔,可是業務多了,就不必定了。
反正我以爲本身手寫Handler,懶得寫,常常見到的狀況是一個Handler來處理多個子線程發來的消息,不是if-else就是switch case,message還要作一些變換啥的,還要考慮有沒有內存泄漏狀況,子線程任務要能及時取消等等,有點煩,除非你設計好了一個良好的封裝。
若是你用過RxJava,保證不再想用Handler了,由於RxJava 運用觀察者模式和鏈式操做符解決了上述不少問題。
RxJava 有四個基本概念:Observable (可觀察者,即被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件。Observable 和 Observer 經過 subscribe() 方法實現訂閱關係,從而 Observable 能夠在須要的時候發出事件來通知 Observer。
使用方法就跟一般的觀察者模式使用差很少,只是一般咱們都只是一對一,即一個觀察者對一個被觀察者,具體使用能夠看看如下兩位大佬的文章。
給 Android 開發者的 RxJava 詳解
當初第一次知道觀察者模式就是由於看到這篇文章。
給初學者的RxJava2.0教程 上下游管道例子講得很好。
我不知道一些大廠對這些線程調度用的是什麼方案,不過從網上的大多技術文章來看,網絡業務方面Okhttp3+Retrofit2+Rxjava2是很主流的。
MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC 的改進版。MVVM 就是將其中的View 的狀態和行爲抽象化,讓咱們將視圖 UI 和業務邏輯分開。
View-ViewModel簡單來講就是數據與視圖組件創建綁定關係,好比單向綁定
這點微軟的WPF作得很高,WPF天生支持mvvm,只要vm中的數據模型值發生了變化,與之對應的view控件就會自動刷新顯示,不在本身用Controller之類的控制view顯示新數據。
其實原理也就是觀察者模式原理,vm爲被觀察者,v爲觀察者,vm有變化,就會觸發vm通知v更新。
EventBus,RxBus主要是能夠解決不一樣組件之間的通訊問題,固然不一樣線程之間也能夠。要比Android的廣播好用點,並且不依賴Contenxt。
單片機有總線,Qt有槽函數,貌似Android就沒有,因此有人就造了Android應用中的總線。
我以爲這些總線的特色就是發佈者是惟一的單例,但能夠被多個訂閱者訂閱,跟Rxjava經常使用的一對一模式有點不一樣。
EnventBus原理 直接上圖
RxBus也是Rxjava的擴展,只是用的是能夠一對多的觀察者
最近不是很流行組件化嗎(分業務module那種),業務module之間的通訊方案應該確定優選XXBus.