最近公司再搞中台化,自己有幸參與其中一個項目的重構,從中學到很多,也有很多感受。
1、准備工作
作為程序猿,重構代碼是很常見的一件事。重構代碼的目的都是為了讓代碼更好地適應后續的發展和變化。
當你打算重構代碼的時候,你先思考下,你為啥要重構?重構勢必要投入一定得時間和人力,在現有的需求的基礎上,需要考慮能否穩定抽出時間來進行重構?人力時間抖允可的情況下,當你打算要重構某部分的代碼邏輯了,還是得先問自己幾個問題,幫助你更好的理清重構的思路:
- 重構代碼邏輯的問題在哪里,你的重構能解決這些問題嘛?
- 新的架構模式有什么優點,后續產品需求變更,對新的框架改動大嗎?
- 你清楚現有業務邏輯嘛,試用場景,方便后續重構后進行回歸驗證?
如果這幾個問題對你來說都不是大問題,基本上對這部分代碼重構,你已經想的比較清楚了。
2、重構設計
1、重構框架
對於框架的重構,你得想清楚舊有的框架都有哪些問題。新框架是完全解決這些問題,還是減少出現這些問題得可能。
對於我負責的這部分業務來說,現有的框架業務邏輯已經比較混亂,兩個不同業務場景混用一套代碼邏輯,業務邏輯相互雜糅在一起。當你修改某個業務功能,很容易對另一個模塊也會造成影響,QA也需要對另一個業務場景回歸,造成人力時間的浪費。
剛好趁着中台輸出的機會,就准備好好重構一把。
對於我參與的這個項目,相對來說比較簡單,整體采用MVP,總體分成三層:接口層,基礎層,業務層。
-
接口層:基於其他團隊開發的一個服務框架實現的調用接口,主要是對第三方提供調起圖片查看器的能力。
-
基礎層:整體基於mvp的設計模式,根據現有的業務邏輯,從中抽取通用邏輯放到基礎層,根據不同的作用,行成不同的接口來輸出。
-
業務層:根據業務,基於基礎層,構建不同的業務層,業務層之間互不干擾。
其實,以前也是采用MVP模式,只不過以前沒有分層,在業務不斷增長的情況下,各種業務邏輯也越來越多,導致整個代碼業務邏輯變得更加混亂。
3、代碼重構的一些體會
-
類與類之間的關系理清楚,減少互相之間的依賴。
-
類A中有比較長的函數的時候,要注意分解。分解的時候要注意局部變量和參數。局部變量過多,可以將其抽到一個類B,這樣調用類B就好了。
-
某個類A包含某個類B,當類A中的某個方法都是和類B相關,就應該把這個方法放到類B中。
-
重復代碼,如果是兄弟類含有相似代碼,就抽到父類中;不同類的可以抽取為公共代碼。
-
一個類A比較臃腫,就得抽出另一個類B出來了。可以把某些相關性比較強的屬性和方法放到一個新的類B里面。類B應該是在類A里面還是放到外面依據屬性而定。
-
如果函數中臨時變量過多,首先是分解臨時變量,盡可能變成 final 形式。然后再看看代碼如何重構比較好,能否拆分成一些細小的函數粒度。
-
對於以前的一段代碼,如果你發現有更好的寫法,那么就用最好的寫法。
-
有時候,為了隱藏實現,會采用代理的形式。可是有時候代理過多,使得代碼復雜的時候,又會移除代理,到底是使用還是不使用依據當前的具體形態來定
-
不要使用魔法數字,使用靜態常量。
-
封裝字段變量,建立取值/設值函數。一般情況下,可以可以在類中自由使用直接變量,不用取值/設值函數。但是當存在繼承的時候,或者子類需要與父類有區別的時候,這時候,重寫取值/設值函數,不影響原有的功能。
-
開發初期,字段比較簡單,直接寫在某個類中。到后期功能越來越多的時候,就會很龐大,這時候就需要抽取對象。
-
重構時最好小步前進,做一次搬移,編譯測試,在搬移,在測試。
-
命名不合理的地方得提出來進行修改;重新命名。
-
重構過程中,會慢慢發現有些方法變得很剪短,這時候可以考慮要不要在調用的地方用函數本體來替換,這樣可以減少方法數,看代碼邏輯也清晰。
-
重構方式,當你要新加一個類的時候,最好的辦法是copy原來的類,然后重命名,刪除無關的方法和變量,在一步一步慢慢調整。最后當你改完以后,再看看是否每個變量都有用到,或者有些變量是不屬於這個新類的。
-
如何處理依賴。或者說當別人依賴你的時候,你怎么去提供一個好的接口,讓別人能夠輕松處理,一兩行代碼足矣。很多其他事都你幫他處理好了。而不是,還要在別人的業務模塊添加一大塊代碼。多從使用方的角度去考慮,現在的方法或者實現是否已經足夠簡潔了。