不少時候,咱們去寫東西的時候,都是悶頭寫,寫到哪算哪,知道一些重構技巧的同窗可能會在邊寫的時候遇到重複就提取出來成方法這樣,但這樣一開始是蠻好的,由於你本身寫的東西,你都知道,可是寫久了,你回頭一看,臥槽,怎麼這麼多小方法?!時間久了,你再回來定位問題的時候,你就會發現方法太多,致使了一個很重要的問題就是,調用層次很混亂,你很難找到你想要的那個方法,總之就這個意思,有遇到這個問題的,天然內心有所體會。java
我舉個例子,好比說,產品需求讓咱們點下一個按鈕,就發個網絡請求,而後讓UI顯示「請求中」,數據回來的時候,再顯示正確的UI。好,那麼應該是這樣的:網絡
void onClick(View v) { switch (v.getId()) { case myButtonId: requestData(); mButton.setText("請求中"); break; } } void requestData() { // ... } void onRequestCallback(Data data) { // 回調來了,更新UI mButton.setText(data.toString()); }
首先,這樣寫是有問題的,我上一篇文章已經說過這樣的問題了。問題在於就地去更新UI了。咱們要用一個統一的地方來更新UI,因而這個要改寫成:動畫
Data mData = null; boolean mIsRequesting = false; void onClick(View v) { switch (v.getId()) { case myButtonId: requestData(); break; } } void requestData() { mIsRequesting = true; // 發起請求 updateView() } void onRequestCallback(Data data) { // 回調來了,更新UI mIsRequesting = false; mData = data; updateView(); } // 用統一的方法更新UI,而且按照View分類 void updateView() { if (mIsRequesting) { mButton.setText("請求中"); } else { if (mData != null) { mButton.setText(data.toString()); } } }
用統一的方法去更新UI,這個說法是很通俗的,我想誰均可以聽明白吧,其實這個事情,是能夠更加抽象的,也就是說,它能夠是一種抽象,適應別的狀況,最近我恰好又作了一些重構的工做,已經成功領悟到這個抽象,那就是:一個方法只去作一件事情,更準確的說,只作一類事情,或者說,一類事情只丟到一個方法裏去作。不知道這樣說,你們聽明白沒有。code
說一個Android裏面的範本吧。想一想onMeasure,onLayout,onDraw方法,單看onDraw方法,就是我上次說到的用統一的方法去更新UI,你三個方法一塊兒看,你就明白了,一個方法只作一類事情,一類事情只丟到一個方法裏去作。排序
onLayout裏面須要的數據,都在onMeasure裏去作好了,存到成員變量上,onLayout直接用,onDraw須要的東西,前兩個步驟都作好了,onDraw直接用成員變量上的東西。換句話說,UI只關心它要展現的數據源,而不關心數據源的改變。內存
UI上的代碼,至始至終都是直接拿着數據源來搞,而邏輯,改變數據源後,不要就地去更新UI,而應該調用更新UI的方法,這樣,維護數據,展現數據,兩個部分就獲得了分離,維護性就是這樣來的。get
那麼,咱們寫一個界面程序,每次都悶頭寫嗎?有沒有什麼套路呢?我就在想,是否是有一種共性,有一種通用的作法,一種高屋建瓴的理解,能夠在一開始就讓代碼漂亮呢。通過我仔細思考和總結後,有了以下的體會。大概是這樣:產品
其實界面程序主要分爲兩個部分:處理數據,處理UIit
處理數據實際上是很寬泛的,包括處理內存的數據,處理本地的數據,處理網絡的數據。你存成員變量,一個列表排序,其實都是處理內存中的數據,下載文件,存配置到文件,其實就是處理本地的數據,發送網絡請求,處理回包,其實就是處理網絡的數據,處理回包實際上是從網絡到內存。class
處理UI其實就是更新UI,或者動畫什麼的,動畫什麼的其實不要緊,隨便搞吧,沒啥。更新UI實際上是時刻關注着內存中的數據,內存中的數據就決定UI要展現成什麼樣。
接下來再思考一下,方法的層次/分類。這個就是說,方法應該分紅哪些類別,哪些方法是有相同的特色。其實能夠分爲三類:
時機/用戶操做
邏輯/處理數據
更新UI
時機/用戶操做,是整個界面程序的驅動力,整個界面能運做起來,徹底是靠這些方法。好比
onCreate onStart onClick onDestory onCallback // 網絡數據回調 onTimer // timer,定時器
這一類方法,是第一層,最早被調用的方法。這些方法被調用後,裏面就是咱們的邏輯部分,或者數據部分,好比用戶輸入了什麼要存起來啊,點了個按鈕發起網絡請求啊。這一層方法,咱們能夠本身命名,本身建,隨便本身搞。好比:
requestData handleData doXXXXXX
最後一類,就是更新UI的方法,按我如今的理解,只須要一個就好了。
updateView
所以第一層方法,能夠調用第二層方法,和第三層方法。第二層方法,能夠調用第三層方法。按照這樣的邏輯進行組織,邏輯就會清晰的多。
總結:
一類工做放到一個方法中處理,一個方法只處理一類工做
要注意整個界面中全部方法的層次,要有總體的把握,不要無謂的爲了抽象,重用增長方法,應當減小方法,讓總體邏輯和調用順序清晰起來
在實際操做以前,先整理下,有哪些網絡請求,數據要如何處理,UI關心哪些數據,而後再着手去作