##目標:避免緊耦合java
本文對原文進行了精簡git
原文連接:Communication patterns for application componentsgithub
##緊耦合 組件之間相互持有引用,以及直接調用方法.在下面的代碼中,MenuFragment持有MagazineActivity的直接引用,所以, MenuFragment 就與 MagazineActivity緊耦合了. 一旦沒有了MagazineActivity,就沒法工做了.數據結構
// 緊耦合示例 class MenuFragment extends Fragment { private void onArticleClick(int articleId) { MagazineActivity magAct = (MagazineActivity) getActivity(); magAct.showArticle(articleId); } }
在這樣的設計中,一個類的修改可能會影響到一大波相關的類,若是開發中還涉及到多個開發人員,那麼這種狀況帶來的只會是痛苦和悲哀..app
鬆耦合的核心就是一種減小組件之間的依賴關係,一個鬆耦合系統能夠很方便的分解爲良構的元素.這樣就使得系統更具備彈性與擴展性. 每一個開發人員能夠維護一個單獨的模塊,並使用標準的協議與其餘部分通訊.工具
##常規解耦方式:接口 (我的補充:接口並非單純指代的java裏面的interface關鍵字,而是指的一種消息規範/協議) 接口是一個強大的解耦工具:類能夠經過接口進行通訊,而沒必要要直接引用另外一個具體類.一個類能夠向外提供一個接口供其餘類與之通訊.在這個抽象層上,其餘類不用關心具體的實現是什麼.優化
//接口示例 class MenuFragment extends Fragment { public static MenuFragment instantiate(ArticleSwitcher articleSwitcher) { MenuFragment menuFragment = new MenuFragment(); menuFragment.articleSwitcher = articleSwitcher; return menuFragment; } ArticleSwitcher articleSwitcher; public void onArticleClick(int articleId) { articleSwitcher.showArticle(articleId); } }
使用接口的缺點:this
##優雅解決方案:消息總線線程
基於發佈/訂閱者模式的通訊方案.發佈者發佈一個通知,訂閱者獲得通知並作出反應,所以,發佈者和訂閱者之間就實現瞭解耦.設計
###實現消息總線
####隱式intent + BroadcastReceiver
經過隱式Intent的通訊能夠看做是消息隊列的一種形式: sendBroadcast(Intent) 或者 startActivity(Intent)是發佈者方法,含有相應IntentFilter的BroadcastReceiver 或者 Activity則扮演訂閱者的角色.
優勢與缺點
優勢:能夠跨應用傳遞,也是Android裏面的標準方法
缺點:沒法傳遞複雜數據,必須經過bundle來傳遞
FluffyEvents 就是一個經過 BroadcastReceiver 實現的消息總線.
("事件"自己也是一種消息,原理仍是訂閱/發佈者模式)
事件自己能夠是任何java類,以下:
// 一個示例事件類 class DownloadProgressEvent { private float progress; public DownloadProgressEvent(float progress) { this.progress = progress; } public float getProgress() { return progress; } }
#####EventBus: 大體原理
EventBus使用合適的數據結構來維持事件以及訂閱者的對應關係,好比Otto使用的方式:
/** Cache event bus subscriber methods for each class. */ private static final Map<Class<?>, Map<EventClass, Set>> SUBSCRIBERS_CACHE = new HashMap<Class<?>, Map<EventClass, Set>>();
每當有訂閱者註冊或者註銷的時候,都會同時更新相應的對應關係,一般,Activity 或者 Fragment會在onResume階段進行註冊,在onPause階段進行註銷.(譯者注:能夠減小內存泄露的問題)
每當有事件發佈的時候,EventBus遍歷整個對應關係,找到全部符合條件的訂閱者方法並執行.
#####Sticky Event
相似Android原生的StickyBroadcast,使得一個訂閱者在任什麼時候候註冊均可以得到這個事件.
##總結
因爲EventBus並非Android的內在機制,所以沒法跨應用傳遞事件.
比較經常使用的兩個EventBus開源類庫:
Square’s Otto:基於註解,在Guava EventBus基礎上針對Android平臺進行了優化
GreenRobot’s EventBus:更好的線程分發機制.
(譯者注: EventBus比較適合組件之間的解耦, 而接口是一個更抽象的概念,還能夠用在view或者其餘方面)
####Android分享 Q羣:315658668