何謂重構

改善既有的程式設計 - 讀後感

Posted by Lil Toby on Monday, August 19, 2019

TOC

何謂重構? p.51-52

對軟體內部結構進行變動,目的是在 “不改變” 他的可見行為的前提下,提高他的可理解性,並修改降低它的成本。

  • 不改變可見行為 / 提高可理解性 / 降低成本
  • 不改變可見行為 / 一系列重構手法修改

    • 偷偷來?
  • 筆者認為

    • 重構是重組的其中一部分
    • 特殊的重組類型
    • 讓程式更容易被理解 > 效能追求
  • 重構要…

    • 如果有人說他在重構好幾天程式沒辦法 work 那他不是在重構 😳
    • 手法
    • Do
      • 提取 function (p.126): 只有收納成一個 function 而不改變行為
    • Dont

      • Change function Declaration
      • Move Function…
    • 遇到 BUG ?

      • 不要修它…bro (雖然會很容易忍不住

兩頂帽子 p.53

  • cosplay
  • 換位思考
  • 勿一心多用

  • 自己挑自己選

    • 開發者、維護者、Reviewer、bla bla bla
  • cosplay結束

    • 推 code
  • A帽: 加入新功能

    • 開始各種嘗試 with 測試
  • B帽: 加以重構

  • Pros

    • 站在不同的出發點,可以帶來到更多意想不到的想法
    • 減少開發中思考紊亂的現象
  • Cons

  • 不換帽子會怎樣?

    • 可能會衍生很多 workaround
  • Keypoint

    • 無論何時你都應該清楚自己戴的是哪一頂帽子
    • 做一天 cosplay 敲一天鐘

為何重構? p.53-57

  • 軟體會劣化,像地平線一樣
  • 怎麼個劣化法?
    • 短期目的修改程式,不注重架構,越寫越糊
    • 慢性病
  • 保持好身材?
    • 消除重複的程式碼
    • 確保每一段程式碼只描述任何事項一次
  • 重構的好處
    • 前人種樹後人乘涼
    • 可以讓之後越來越省時間
    • 把該記住的東西寫進程式
    • 搞清楚結構 > 找出 bug
    • 提升程式編寫速度 (p.56 圖表)
  • 設計耐力假說
    • 投注設計良好程式 > 開發耐力 up
    • 不會因為一直爆炸而想放棄?
    • 一開始寫就開始劣化了QQ

重構時機? p.57-63

  • 三次法則 (Rule of three)
    • 相同的程式碼片段重複出現三次以上
    • 收納了 收納了

預備性

  • 開始之前 (久久遇到一次
  • 閱讀 > 研究 > 檢視複製貼上的 function 們
  • Parameterize Function p.358

理解性

修改程式碼前…

  • 藉由重構理解程式
  • 手癢的感覺
  • 先確定自己對程式碼的理解是否正確
  • 慢慢看到原先無法看到的設計問題

打掃性

已經了解程式碼了…

  • 需要做一些取捨以免分心太久
  • 要邊評估這垃圾是不是太大包
  • 等下一台垃圾車
  • 以免玩火自焚
  • 筆者以越來越乾淨的營地做比喻
  • 以不破壞程式碼運行為原則

計畫性與伺機性

  • 筆者重申重構應該是跟編寫程式同捆包的
  • 重構並不是修正或清除醜程式的

長期重構

公司有點大間…

  • 抽換整個程式庫
  • 筆者提供一個方法
    • Branch By Abstraction
    • 建立新的抽象當作介面 for 新跟舊的程式庫

程式碼複審時重構

  • 在開發時就要換位思考自我檢視 (戴帽子)
  • 在 review 別人的 code 時思考怎麼重構
  • 對於建議他人改好後的程式碼輪廓更為清晰
  • 會看到一個
  • 筆者建議
    • 不要用 PR 的方式
    • 最好可以跟原作者並肩坐著一起看程式碼
    • 有夠難…

該跟主管報告嗎?

  • 不要說出來…..Q__Q
  • 應該要保持 先重構再加新功能 的原則
  • 把重構當作理解程式碼的方式

何時不該重構?

  • 不需要修改的程式碼就不會重構他
  • 除非有理解它運作的必要
  • 醜就讓它醜下去吧…
  • 別走火入魔啊施主
  • 還有一種可能
    • 直接砍掉重練比較快!!!

重構難題 p.64-71

重構的目的是加快編寫速度,用更少勞力換取

  • 減緩新功能完成速度

    • 重申重構目的是為了提升工作速度
    • 其實比較多根本是過少重構
    • 有經驗的透過大量指導帶領沒經驗的進行重構
    • 完全是出於經濟目的
      • 更快速添加新功能、更快速地修復 bug
      • 而不是寫出 “出色” 的程式碼
  • 程式碼擁有權

    • 舉例: API deprecate 的問題
    • 避免形成專案之間的壁壘
    • 讓大家都有權限可以互相改對方的程式碼與分支
  • 分支

    • 困難在於處理語意的變動
    • 會隨著分支壽命增長而惡化
    • 可以透過整合 CI 大幅降低合併的複雜性
    • 但要設法確保主線是健康的 & 將大型功能拆小塊
  • 測試

    • 重構就是要在發生破壞時 快速地抓到錯誤
    • 重構會不會引入 bug?
      • 沒有寫測試就會!!!
    • 幫助你心安理得的重構
    • 在重構的同時 test runner 就告訴你哪裡想錯了
    • 有一個無形的 mentor 在旁邊
    • 測試為 CD 的關鍵元素
    • 在覆蓋率不佳的大型基礎程式怎麼辦?
      • 只使用一組有限的、已證實為安全的重構原則
  • 老舊程式碼

    • 重構是理解它的好幫手
    • 協助換掉一些語意不明容易誤導的函式名稱
    • but 還是要加測試R
    • 筆者建議
      • 可以看看 Working Effectively with Legacy Code
      • 試圖插入測試的接縫
      • 危險 but 必要
      • 講到最後還是建議最好一開始就寫測試 (再鞭一次始作俑者)
      • 不建議一次到位而是頻繁地回來重構
      • 個人理解為避免鑽牛角尖 or 陷入重構深淵
  • 資料庫

    • 業配朋友的 逐漸改善重構 資料庫 的方法
    • 感覺下列兩種做法
      • 是把變動放進某張 table 存起來
      • 把程式碼存成 migration script
      • 不過不是都 sql 檔嗎?不是很可以理解
    • 資料庫版本遷移
      • 改寫欄位
      • 遷移腳本
      • 可以分多次發佈至 PROD
      • 是有點像 API 從 v1 -> v2 的意思嗎?

重構架構與 Yagni p.71

  • 一開始寫程式碼就是劣化的開始
    • 開始動手前都還有機會
  • 重構的觀念會幫助你敢大刀闊斧的修改程式碼
    • 從南天門一路砍到蓬萊東路
  • 彈性機制反而會降低對變化的反應能力
    • 因為計畫永遠趕不上變化
    • 一股腦兒加入 “有彈性” 的參數會讓函式更為複雜
    • 重構可以養成 斷捨離 的判斷能力
    • 彈性 ↑ 複雜度 ↑
  • 設計方法們
    • 簡單設計: simple design
    • 漸增設計: incremental design
    • yagni: you aren`t going to need it
  • 具備 事前思維 可以有效節省時間

重構與更廣泛的軟體開發程序 p.73

  • 業配 極限編程 時間
    • 持續整合
    • 自檢程式碼
    • 重構
  • 敏捷再敏捷

重構與性能 p.74

  • 重構與效能並不是正比的
  • 重構雖然有可能讓軟體跑得更慢,但也讓我們更容易調整軟體的性能
  • 快速開發方法
    • 時間預算法
    • 持續關注法
    • 利用 90% 的數據

重構的出處? p.77

  • smalltalk 的故事
  • 程序猿是無法第一次就寫出清晰的程式碼的
  • 筆者與 Kent 合作開發打破天靈蓋
    • 看到重構對生產力與品質造成的影響 Woooo
    • 所以寫了這本書

自動重構 p.79

  • 許多 IDE 已經整合一些自動化重構的功能了
  • 譬如說改變引入 moduke 名字 IDE 就會自動連動了…
  • 還在業配 smalltalk
  • 各種 IDE 自動重構史
  • 正確的自動重構必須處理 語法樹
  • 講到底還是寫好測試比較安全
    • 不然搞爛了還是要自己收拾蠻麻煩的

個人心得

  • 個人認為重構是一種練習,當習慣用重構理解程式碼會有效加快開發速度
  • 不過重構常常會因為拿捏不當造成混沌
  • 所以理解基本的重構原則是非常重要的

參考連結

- 請 Toby 喝珍奶,你請我就喝 -

Lil Toby Blog

YA~大杯還小杯~看你誠意 ❤ ️

使用手機掃描 QRCODE 完成 pay 下去就對