一個關於寫好代碼的案例

今天上班修復一個bug的時候,發現本身原來寫的一個函數已經被改的醜陋不堪。做爲一個有原則的程序員,這樣的事情最不能忍受,拯救代碼之餘,也有了下邊的一些關於如何寫好代碼的想法。程序員

在訂單系統裏有一個計算髮貨倒計時和確認收貨倒計時的邏輯. 這個函數剛剛寫出來時是這個樣子, 看起來沒什麼大問題問題, 函數不太長, 邏輯也很直觀. 固然若是較兒真的話這個函數有優化的空間, 可是如今動力不足, 不至於去重構. 函數

Paste_Image.png

若是沒有新的需求驅動修改這個函數的話, 可能這個函數一生也就這樣了. 優化

忽然有一天, 新的邏輯來了訂單能夠支持延遲發貨和收貨. 因此相應的這兩個倒計時也要加上extend的天數. 接下來, 這個函數演變成這個樣子. spa

Paste_Image.png

如今這個函數看起來不爽了. 1. 重複的代碼: (Instant.now().getEpochSecond() - order.getUpdatedAt().toInstant().getEpochSecond())出現了兩次, getEpochSecond()出現了四次; 2. 對××DaysCount > 0 的判斷也出現了兩次; 3. 冗餘的,嵌套的if結構, 這直接影響了代碼的整潔和美觀. 函數不大, 壞味道很多. 除了這些壞味道, 裏邊還隱藏着時間單位的錯誤(姑且命名這個錯誤爲壞壞). 其實這個時候重構的時機已經成熟了. rem

若是當時代碼修改者在寫完這段邏輯以後, 駐足反思, 重構一下, 那麼這段代碼會以一個全新的面孔面對下一個代碼修改者. 無疑一個邏輯清晰, 展示美觀的函數, 是你留給隊友最大的驚喜. get

可是, 這樣的驚喜最終仍是沒有留給隊友. 終於有一天, 壞壞浮出水面, 致使頁面顯示錯誤, 出現了離譜的天數. 這個bug交給了蛋蛋解決. 蛋蛋眼明手快一眼定位到了壞壞. 把時間單位統一爲SECOND, 一切working as expected. it

高興之餘, 蛋蛋點着一根菸, 眉頭緊鎖, 如有所思... 其實他腦子裏在演繹着重構心法:io

  1. 首先我要把計算日期差值的重複邏輯去掉. Java8, 提供了方便的Duration類, 哪一個Low B笨到本身去計算(卻不知, 這段代碼就是蛋蛋本身寫的);ast

  2. xxDaysCount > 0, 這個if判斷, 我想經過加法結合律去掉. 通過縝密的調查確實是這樣能夠這樣作, xxDaysCount在程序的上下文中是非負的, 用加法結合律改進沒有問題;class

  3. time這個命名也有問題, 詞不達意.
    "啪啪啪..." 半根菸以後, 塵埃落定. 代碼被整容成下邊這個樣子. 蛋蛋拿起剩下的半根菸, "嗯, 代碼少了六行, 明顯的重複代碼也沒了, 討厭的if也被我幹了..." 看起來比較順眼了.

Paste_Image.png

心得:

  1. 代碼不會變好, 只會逐漸變爛. 每一次修改代碼都會讓代碼變爛, 多思考, 多重構能夠代碼變爛的速度減慢.

  2. 每次修改代碼都是重構的最好契機.

  3. DRY & DRFY. 好代碼最基本的兩個原則: Don't Repeat Youself; Don't Repeat Fucking Yourself.

相關文章
相關標籤/搜索