2018 終了,是時候秀出我的 Git 進化日誌了!
作者 | 拭心
責編 | 郭芮
一眨眼已到 2018 年底,我入職喜馬也一年多了,這一年裡成長了不少,但對外輸出少了很多,主要原因還是太懶。今天趁懶癌沒發作,跟著 Git 提交日誌,回顧一下這一年多寫的程式碼。
剛入職一個多月的提交
可以看到,我的提交日誌還是比較清晰的,當次提交做了什麼基本可以一目瞭然。
剛開始那一個月,主要是熟悉專案,然後做一些比較簡單、關聯性比較低的需求,比如直播首頁、個人資料卡的修改。
新人對專案瞭解不夠,最好不要一上來就分配業務狀態比較複雜、涉及面比較廣的需求,那樣風險太大。
這個階段我做的還算可以,變數、常量命名合理易懂,異常情況考慮的也還算周到,上線後基本沒有什麼 bug(其實是做的功能比較簡單哈哈)。
入職兩個多月的提交
十一月主要做的是建立直播,這個需求比較典型,是一個頁面有多種狀態,編輯、預覽、修改等等。
開發這種頁面樣式、介面比較相似的需求,最好抽象出共同的基類或者介面,然後根據不同邏輯選擇不同的實現,避免在其中通過 if-else 新增各種判斷邏。這種模式就是常說的“策略模式”。
比如我這樣:
private ILiveCreateOrEdit getImplByType(int type) {
switch (type) {
case TYPE_LIVE_PREVIEW:
return new LivePreviewInfoImpl();
case TYPE_PREVIEW_EDIT:
return new LivePreviewEditImpl();
default:
case TYPE_COMPOSE:
return new LiveCreateImpl();
}
}
ILiveCreateOrEdit 裡定義了建立直播、直播預告、編輯直播都要有的功能,比如初始化 UI、請求介面、點選固定按鈕的邏輯。三個實現裡完成對應狀態的佈局顯示和介面請求,避免了使用 if-else 的雜亂。
不僅僅是頁面相似的,邏輯相似的也可以使用這種模式。比如一些圖示、徽章、掛件的下載、查詢,都是一樣的邏輯,我都把他們放到了一個管理器裡,定義介面然後再具體實現。
我們新開發一個需求時,不要急著實現,可以先花點時間想想現有的哪些需求可能和這個類似,能否把他們的邏輯抽象出共同之處,這樣後面有類似的需求可以基於這個共同的直接進行拓展開發,看似現在是多做了工作,其實是為以後節省時間。
繼承優於拓展;
重複使用的佈局、類,最好抽象出共同的基類或者介面,然後通過繼承實現,避免在其中通過 if-else 新增各種判斷邏輯;
以前總喜歡把一個類用到很多業務,結果導致在裡面充斥了大量的判斷程式碼,時間久了自己維護都費勁,實在是不好的風格。
入職三個多月的提交
從日誌可以看到,這個月我主要在解決一些 bug。
其中一部分問題屬於 UI 問題。我開發時遇到不太舒服的樣式、互動會自行修改,然後拿著修改後的找產品、設計師溝通,有的時候他們會被我的機智所打動,同意修改。但更多時候,我的意見都被駁回,看來我的審美還是不夠好 0.0。
還有一部分問題是“過度優化”導致的。有時候寫業務,不由自主的想優化一下,比如複用、回收、預載入。本意是好的,但奈何我心太粗,只想著優化的好處,沒有針對優化可能導致的問題做出處理。比如複用時的狀態異常處理,物件池的額外開銷,預載入選擇的時機等等。
任何優化都是雙刃劍,不僅要考慮益處,也要考慮代價。
再有就是對自己寫的程式碼不熟悉導致的。比如對 View.post() 的實現不熟悉;對 LruCache 的 maxSize 和 sizeOf() 理解不到位;對 CopyOnWriteArrayList 的迭代器不熟悉;對專案元件生命週期不熟悉等等。
對專案、對執行在諸多使用者上的程式碼要有敬畏心,對自己所寫的要儘可能多的理解,確保沒有問題。
最後就是那時候提交程式碼沒有養成 review 的習慣,偶爾會提交了錯誤的程式碼,比如 refactor 影響到不相干的程式碼。後面糾正了這個問題,commit 前基本都會檢查。
做的不好的是,在提交 log 裡沒有寫清楚 bug 原因,對於一些可能再次犯的問題,應該在 log 上寫清楚。
使用英文作為日誌的提交
這個階段我不知道吃了什麼藥,開始使用英文寫提交日誌,可能覺得很酷吧。
回過頭再看,發現這種提交,根本不直觀,因為一些細節不好用英文表達,提交日誌就寫的比較簡單、模糊,在後面排查問題時,無疑增加了難度,不太建議這樣。
上線一個大功能前的提交
五六月份開發了一個相對複雜的功能,這個功能涉及到的狀態、異常情況比較多,出的 bug 就比較多,於是有了上面這樣整齊的解決 bug 日誌。
這個經歷能學到哪些知識呢?
拿到需求,先不考慮如何實現,而要考慮這麼做是為了什麼,知道目標後,哪怕當前需求因為技術無法實現或者實現成本太大,也可以嘗試提出替代方案,而不至於直接推掉。
拿到業務,先分層,介面 -> 資料 -> 訊息,雖然程式碼不是 MVP 模式,但思考可以像 MVP 一樣先定義各層介面,然後確定依賴,不同類之間儘量不要直接依賴類,而要依賴一個介面。
避免直接依賴;
類 B 中呼叫類 A 很多方法的話,就讓類 A 實現介面 X,然後 B 持有 X 的引用,那樣將來類 A 修改繼承自誰,也不會影響這些舊程式碼;
也不要直接呼叫其他類的成員,通過 getter 方法呼叫,那樣在值異常時做一些處理可以直接在方法內部完成,而不需要修改所有呼叫的地方。
還得重視異常情況的處理。比如弱網、飛航模式、App 奔潰、強殺應用,這種狀態恢復到正常狀態後,如何恢復現場呢?客戶端樣式狀態最好以服務端為準,一些比較敏感、常變的可以使用輪詢。
以服務端資料為準,但客戶端要做好兜底,直接影響狀態的資料要做兜底,資料異常時提供預設狀態好過顯示異常。
優化相關的提交
可以看到,我的優化日誌也不夠詳細,沒寫清楚都做了什麼優化。以後得把優化的內容也寫明白。
靜態程式碼檢測幫助我發現了很多細節問題,比如:
StringBuilder 要拼接的字串大於 16 時,構造需要宣告初始容量,不然會頻繁擴容;
在使用 StringBuilder.append() 方法連線字元時,避免使用 string 型別,用 char 型別連線字元;
不要 new 包裝類,使用 valueOf() 方法代替;
Integer.parseInt() 和 Integer.valueOf() 的正確選擇;
DateFormat 的多執行緒不安全問題;
…...
還有一些業務邏輯的優化,比如資料對比、區域性重新整理、動畫效率、記憶體洩漏等等,都是比較常見的。業務需求比較多,在效能方面做的還不夠,這一點比較慚愧。
和領導溝通,說到,除了敬畏心、責任心,開發還需要具備追求完美的心態,對自己寫的專案要多玩、多用,主動發現不足之前並優化。後面我得更加關心效能和體驗。
總結
在沒有養成寫週報、正確對待提交日誌的習慣之前,我在回憶工作內容時,常常會很迷茫,記不起自己究竟做了什麼,學到了什麼,產生了什麼價值。
過去的這一年多,我的提交日誌還算有些價值,跟著日誌簡單回顧了一下這一年多做的事,發現可以改進的地方很多,後面還得繼續努力才行啊!
改進意見:
log 資訊前面使用 tag 標明分類,[feature] [fix] [perf];
提交粒度要夠細,以備不時之需,完成獨立的功能就提交;
日誌資訊要寫清楚,做了什麼功能,解決了什麼問題(原因是什麼),優化了什麼(有什麼改進);
需要經常回顧工作內容,提出改進意見。
作者:張拭心,長期在 CSDN 上寫作,CSDN 部落格專家,公眾號“zsx躍遷路”維護者。熱愛讀書寫作,目標是寫出有趣的技術書,目前研究方向為前端和移動端。本文來源於個人部落格:https://blog.csdn.net/u011240877/article/details/84001196。
宣告:本文為作者投稿,版權歸其個人所有。
熱 文 推 薦
☞BAT 縮招,AI 躋身 2019 年最賺錢職業榜首!(附薪酬表)
☞支付寶闢謠交易 5 萬受監控;App Store 宕機;谷歌拋棄 AI | 極客頭條
☞別說創業維艱,16歲開發者從輟學歧視死亡威脅, 到開發出爆款應用, 她的人生遠非成人想象
print_r('點個好看吧!');
var_dump('點個好看吧!');
NSLog(@"點個好看吧!");
System.out.println("點個好看吧!");
console.log("點個好看吧!");
print("點個好看吧!");
printf("點個好看吧!\n");
cout << "點個好看吧!" << endl;
Console.WriteLine("點個好看吧!");
fmt.Println("點個好看吧!");
Response.Write("點個好看吧!");
alert("點個好看吧!")
echo "點個好看吧!"