為什么你的android代碼寫得這么亂
Android上絕大多數的代碼,都是由事件觸發的,或者說,幾乎所有代碼都是寫在某個回調上的,比如onCreate, onPause, onClick,onBind等等,而這些回調函數,全都是一個個的函數,也就是說,是一個一個小的過程。
單個事件內完成的功能對于一些簡單的情況,在某一個回調內部就能完成的事件,大致上都是在回調中創建一個A類的對象,然后調用A類的某個方法,這個方法里面又用到了B類和C類的對象,經過了一系列翻云覆雨的計算,我們最終得到了一些數據,用TextView顯示了出來,比如點擊一個按鈕彈出一個Toast顯示當前軟件的版本號這樣的功能,只需要一個onClick就可以完成。所以我們可以粗暴的理解為,所有面向對象,都是基于過程的。因為只有一系列對象,按照某種特定的順序組織起來,調用里面特定的方法,才能得出一個有意義的功能。這也解釋了為什么很多SDK,就給你個方法,告訴你,你什么都不用管,在Application的onCreate里面調一下這個方法就好了。

再比如一些稍微復雜一點的功能,需要多個事件配合,比如計算器,當用戶按下第一個數字的時候,觸發了onClick事件,你要把這個數字保存為activity的某個字段,接著,用戶按下了加號和第二個數字,你都要這樣保存起來,以便于在最終用戶按下等號的時候,你能把以前的一系列輸入獲取到,以計算出一個結果。也就是說,當一個功能需要多個事件配合完成的時候,我們做的事情就是把各個事件的最終結果從局部作用域提升為類的字段,即提升可見性。當可見性不那么好提升的時候,垃圾代碼就出現了。比如這樣的代碼:

Context是非常常用的一個對象,無論是發廣播,還是啟動activity,啟動Service,獲取SharedPreferences,獲取資源等等,許多地方都需要用到context,加上Application對象一直存在,于是就想出了這么個辦法。
我并不反對通過提升可見性來實現多個事件之間的配合,比如計算器的例子,提升可見性就是一個簡潔優雅的解決方案。但是很多時候為了提升某些字段的可見性,將字段設置為靜態字段是沒有必要的,而且有可能造成內存泄漏。
什么樣的代碼簡潔清晰我們之所以代碼寫得那么難受,很多時候是因為給的接口不夠“多”,試想一下,如果SD卡的文件被改動有回調,手機位置發生變化有回調,網絡狀態一變化就有回調,這會讓很多功能實現起來變得非常簡單。

什么事件需要寫回調?通常是那些破壞代碼簡潔的邏輯,比如耗時的操作,像網絡請求,大量計算,獲取地理位置等,或者一直在被監聽的事件,比如推送到本地的消息,文件被篡改、網絡狀態等。讓那些簡單不耗時的操作,比如讀取文件,彈出Toast或者設置TextView分門別類的放在這些回調里面,讓人一目了然。
這些是無法用MVP,MVVM等架構解決的,原因很簡單,因為無論怎么分層,這些回調都是需要的,分層只是把這些回調放在不同的文件里面而已。軟件分層一方面是為了容易移植,另一方面是為了分離純Java的代碼,方便做單元測試。
回調是讓代碼簡潔的方式之一,在我們實際編碼的過程當中,在此前的基礎上,還可能會遇到下面這個非常常見的問題。
臃腫的回調無論我們愿不愿意,我們都是在以填充各種事件的回調來編寫android代碼的,這就導致一個問題,當業務邏輯越來越復雜的時候,我們就很有可能會在同一個回調中,編寫多個毫不相關的任務的業務邏輯。
當一個事件的回調中承載的事情越來越多,面向過程的思想就體現的越來越明顯。在實際編程的過程當中,我偏向于同時具備面向對象和面向過程兩種思維方式,而不是簡單粗暴的認為:面向對象高雅,面向過程低俗。它們的本質是相同的,褪去多態的光環,面向對象只是一種將函數分門別類存放的一種建議。
如何解決回調過于臃腫的問題?
優先考慮將這個回調的事件細分。典型的就是AbsListView類的onTouchEvent,onTouchEvent里面的邏輯非常復雜,為了避免堆積在一起過于凌亂,onTouchEvent被分解成了onTouchDown,onTouchMove,onTouchUp以及onTouchCancel。這樣一大塊代碼就會被打散,交給更細致的回調來分擔。

如果某個事件的回調中執行的業務邏輯,并不是一類(比如發送網絡請求刷新了一下ListView和讀取了一下配置文件),不像onTouchEvent這樣可以細分,那么問題就會變得比較麻煩,因為我們用事件的回調來解決問題的時候,我們真正想要的是回調函數執行的時機,比如onResume就在那個特定的時機會被調用,如果你需要的就是這個時機,你就只能老老實實的在這里寫代碼,別無他法。為了代碼簡潔,我們能做的就是盡可能的將這個承擔了多個職責的回調寫的足夠簡單,最好是沒有循環,沒有分支,就是幾個赤裸裸的函數放在哪里,讓人一目了然。

認識到android軟件開發是在各種各樣的回調上搭建一切功能,是編寫代碼的第一步,是未來學習設計模式的基礎。
文/吳晨(簡書作者)原文鏈接:http://www.jianshu.com/p/8182921fea87相關文章:
