重構-讀書筆記

有一本書叫做《重構 改善既有代碼的設計 》,個人感覺寫的還蠻不錯的,在讀這本書時候做的一些讀書筆記,分享給大家:

一點個人總結

重構可以理解為是一套體系,在這套體系中主要包括幾個東西:

  1. 什么樣的代碼需要重構
    ------首先明確什么樣的代碼需要重構,通過代碼的壞味道來分辨出有問題的代碼
  2. 什么時候去重構
    --------在工作中,在什么時間,什么場景更適合推動去重構
  3. 怎樣避免引入新的問題
    ---------重構的第一步是為程序建立一組可靠的測試環境,用來保證重構不會引入新的bug重構方法
  4. 重構的方法
    ----------有一系列已經總結出來的方法和范式,可以碰到情況,直接去套

讀書筆記

1. 首先什么樣的代碼需要重構:

1:函數過長
2:參數過多
3:類過大
4:類的功能不合理(A類中一個功能,大量依托B類中的參數,更應該把次功能移到B類)
5:平行繼承關系(解決辦法可以考慮在一個繼承關系中引用另一個繼承關系中的類,然后通過移動類的參數和方法,消滅另一個繼承關系)
6:switch語句
7:如果修改一個小功能,要對多個類進行修改
8:一個類經常因為不同業務或者方向上的功能修改,而去修改這個類
。。。

2. 何時來重構:

1:Review代碼
2:修改Bug
3:增加新功能
同時注意一個原則增加功能和重構進行分離,重構時候專注重構,當增加功能時專注增加功能

3. 建立可靠的測試環境:

1:這個首先是自動化測試的環境,過于不過,對不對自動來判斷
2:主要加大力度測試容易出錯的地方,簡單的set get不用來搞
3:重點測邏輯邊界的地方
4:有bug,要增加測試case

4. 重構方法:

細化方法,更小顆粒度
方法移動到別的類
抽象出新的類
內部類

隨手記

1:分解長長的函數
<1>對于函數中的局部變量進行查看,對于那些會改變的局部變量可以考慮通過另一個函數的返回值獲取
<2>在程序實現中,往往有些組合類,它里邊的功能依托于多個類來實現,比方說其中一個比較重要的功能函數,它只使用了其中一個組合類的各種方法和變量來實現功能,那么該考慮下下這個方法應該移到這個組合類中來實現
<3>在一個類里用其它類的屬性做switch判斷的話,就說明不太靠譜,如果真的需要應該在原來的類里去做這個判斷
2:重構的目的在于讓軟件更容易讓人理解和修改,但不影響軟件或者程序對外的表現
3:改進設計的一個重要方向就是消除重復代碼

重構和添加新功能進行分開進行,重構時專心重構,添加新功能時只增加新功能

何時重構:
1:添加功能時進行重構
2:修補錯誤時進行重構
3:Review代碼時進行重構
性能優化,首先是有性能問題,通過數據找到性能消耗的點,不能只主觀臆測
代碼的壞味道
一些比較好的原則,把總是一起發生變化的東西放到一起
1:重復代碼
<1>同一個類中有重復代碼,提一個函數出來
<2>兄弟類中有重復代碼,將代碼置于父類
<3>毫不相干的兩個類中有重復代碼,搞一個單獨類出來,然后進行引用,或者其它方式進行引用
2:過長函數
有一個簡單判斷條件,如果覺著需要寫注釋了,可以考慮搞一個新的函數出來,函數命名一定要能表現出功能來,即便是導致代碼量更長了,但是這樣看著會更加明確
3:過大的類
如果用同一個類干太多事,往往就會有一堆變量,可以將幾個相關的變量提到同一個類中處理
太多代碼的話,可以考慮先內部重構,把大函數中的重復代碼做成小函數
4:參數太長
考慮傳入參數用類來代替
5:發散式變化
如果一個類經常因為不同原因在不同方向上發生變化,例如修改數據庫在這個類需要修改三個函數,新增一個工具需要在這個類修改四個函數,那么應該分成兩個類比較合適,每個類真對一種修改
6:霰彈式修改
如果遇到一個變化會對多個類進行小的修改,可以考慮把這些個修改抽象到一個類中
7:依戀情結
如果實現一個功能,調用類另一個類的一堆函數,那應該考慮把這個功能放到另一個類中,如果這個功能比較復雜,用到了多個類的多個字斷,判斷哪個類擁有最多彼此函數使用的數據,將這部分數據和功能放到哪個類中
8:數據泥團
在很多地方看到相同的三四項數據,兩個類中相同的字斷,許多函數簽名中相同的參數,可以將這些參數抽象到類中
9:switch
switch語句最大的問題是重復,常會發現同樣的case語句到處存在,要修改就得到處改
當看到switch語句時候,考慮多態來實現
10:平行繼承體系
當在一個類繼承體系中,增加一個類時,往往需要在另一個繼承體系中增加一個類
解決辦法是讓一個繼承體系的類引用另一個繼承體系的類

構筑測試體系
1:確保所有測試自動化完成,讓他們檢查自己的測試結果
2:考慮可能出錯的邊界,把主要測試放在這
3:每收到一個bug時,考慮加一個測試
4:在最擔心出錯的地方搞單元測試
測試應該是一種風險驅動的行為,測試的目的是希望找出現在或未來可能出現的錯誤

重新組織函數
1:提煉函數
有一段代碼可以組織在一起并獨立出來,將這段代碼放進一個獨立函數,并讓函數名稱解釋該函數的用途
當看見一個長長的函數或者看到一段注釋才能理解功能的函數時,將這段代碼放進一個獨立函數中,注意的是需要把這些函數命名的比較好。當函數細粒度越小,被服用的可能就會越大
函數的命名以做什么為命名,而不是怎樣做
2:以函數對象取代函數
如果一個大型函數,內部有多個臨時變量,而代碼間的邏輯又各種引用這些個臨時變量,直接運用提煉函數的話,應該會導致每個提煉函數都有一批參數傳遞,就不太適合直接提煉函數,這時候可以采用一個辦法是新建一個類,這個類接受本身這個實例,以及這些個臨時變量,在新類里就可以有final的全局參數,有個委托參數來實現原來大型函數的功能,而在新類里對于這函數可以來提煉函數了,這些個變量已經是全局變量了
對象之間搬移特性:
搬移函數
如果類中的一個函數與其他類打交道的比與自己的類打交道還多,可以考慮將這個函數搞到那個類中
搬移字段
根搬移函數差不多意思
提煉類
如果某個類干了兩個類干的事,建立一個新類,將相關的字讀和函數遷移過去

大家對于文章內容,有疑問或者希望有內容補充修改的可以在評論中提,筆者會秉承互聯網產品哲學,小步快跑,快速迭代,不斷修改和優化文章內容。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容