1. 程式人生 > >回顧我這一年多的 Git commit 日誌

回顧我這一年多的 Git commit 日誌

一眨眼已到 2018 年底,我入職喜馬也一年多了,這一年裡成長了不少,但對外輸出少了很多,主要原因還是太懶。

今天趁懶癌沒發作,跟著 git 提交日誌,回顧一下這一年多寫的程式碼。

剛入職一個多月的提交

2017.10

可以看到,我的提交日誌還是比較清晰的,當次提交做了什麼,基本可以一目瞭然。

剛開始那一個月,主要是熟悉專案,然後做一些比較簡單、關聯性比較低的需求,比如直播首頁、個人資料卡的修改。

新人對專案瞭解不夠,最好不要一上來就分配業務狀態比較複雜、涉及面比較廣的需求,那樣風險太大。

這個階段我做的還算可以,變數、常量命名合理易懂,異常情況考慮的也還算周到,上線後基本沒有什麼 bug(其實是做的功能比較簡單哈哈)。

入職兩個多月的提交

2017.11

十一月主要做的是建立直播,這個需求比較典型,是一個頁面有多種狀態,編輯、預覽、修改等等。

開發這種頁面樣式、介面比較相似的需求,最好抽象出共同的基類或者介面,然後根據不同邏輯選擇不同的實現,避免在其中通過 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 新增各種判斷邏輯。

以前總喜歡把一個類用到很多業務,結果導致在裡面充斥了大量的判斷程式碼,時間久了自己維護都費勁,實在是不好的風格。

入職三個多月的提交

2017.12

從日誌可以看到,這個月我主要在解決一些 bug。

其中一部分問題屬於 UI 問題。我開發時遇到不太舒服的樣式、互動會自行修改,然後拿著修改後的找產品、設計師溝通,有的時候他們會被我的機智所打動,同意修改。但更多時候,我的意見都被駁回,看來我的審美還是不夠好 0.0。

還有一部分問題是**“過度優化”導致**的。有時候寫業務,不由自主的想優化一下,比如複用、回收、預載入。本意是好的,但奈何我心太粗,只想著優化的好處,沒有針對優化可能導致的問題做出處理。比如複用時的狀態異常處理,物件池的額外開銷,預載入選擇的時機等等。

任何優化都是雙刃劍,不僅要考慮益處,也要考慮代價。

再有就是對自己寫的程式碼不熟悉導致的。比如對 View.post() 的實現不熟悉;對 LruCachemaxSizesizeOf() 理解不到位;對 CopyOnWriteArrayList 的迭代器不熟悉;對專案元件生命週期不熟悉等等。

對專案、對執行在諸多使用者上的程式碼要有敬畏心,對自己所寫的要儘可能多的理解,確保沒有問題。

最後就是那時候提交程式碼沒有養成 review 的習慣,偶爾會提交了錯誤的程式碼,比如 refactor 影響到不相干的程式碼。後面糾正了這個問題,commit 前基本都會檢查。

做的不好的是,在提交 log 裡沒有寫清楚 bug 原因,對於一些可能再次犯的問題,應該在 log 上寫清楚。

使用英文作為日誌的提交

english log

這個階段我不知道吃了什麼藥,開始使用英文寫提交日誌,可能覺得很酷吧。

回過頭再看,發現這種提交,根本不直觀,因為一些細節不好用英文表達,提交日誌就寫的比較簡單、模糊,在後面排查問題時,無疑增加了難度,不太建議這樣。

上線一個大功能前的提交

2018-friends-mode

五六月份開發了一個相對複雜的功能,這個功能涉及到的狀態、異常情況比較多,出的 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 的多執行緒不安全問題

還有一些業務邏輯的優化,比如資料對比、區域性重新整理、動畫效率、記憶體洩漏等等,都是比較常見的。業務需求比較多,在效能方面做的還不夠,這一點比較慚愧。

和領導溝通,說到,除了敬畏心、責任心,開發還需要具備追求完美的心態,對自己寫的專案要多玩、多用,主動發現不足之前並優化。後面我得更加關心效能和體驗。

總結

在沒有養成寫週報、正確對待提交日誌的習慣之前,我在回憶工作內容時,常常會很迷茫,記不起自己究竟做了什麼,學到了什麼,產生了什麼價值。

過去的這一年多,我的提交日誌還算有些價值,跟著日誌簡單回顧了一下這一年多做的事,發現可以改進的地方很多,後面還得繼續努力才行啊!

改進意見:

  1. log 資訊前面使用 tag 標明分類,[feature] [fix] [perf]
  2. 提交粒度要夠細,以備不時之需,完成獨立的功能就提交
  3. 日誌資訊要寫清楚,做了什麼功能,解決了什麼問題(原因是什麼),優化了什麼(有什麼改進)
  4. 需要經常回顧工作內容,提出改進意見