架構重構之禪
{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"引言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Refactoring 一直以來都是項目開發中的熱點和難點,考慮到更通俗的易懂,本文是什麼("},{"type":"text","marks":[{"type":"strong"}],"text":"what"},{"type":"text","text":"),爲什麼("},{"type":"text","marks":[{"type":"strong"}],"text":"why"},{"type":"text","text":")以及怎麼做("},{"type":"text","marks":[{"type":"strong"}],"text":"how"},{"type":"text","text":")的三個點進行展開講解。因爲重構不是獨立的對某一塊代碼優化,而是讓系統以及代碼的相互協調作用表現最佳的改進過程,所以文章的內容可能存在交集的部分,而已理解的情況下,大家可自行跳過。"}]},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"概括"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"重構本質"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重構是在不創建新的功能方法前提下,改進系統代碼的過程,讓代碼邏輯和架構設計變得更加乾淨和清晰"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"重構意旨"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重構主要的目的在於解決項目存在的技術債務,將原有的代碼和設計更清晰簡單,提高系統性能。"}]},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"代碼重構(what)"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"重構後的代碼基本具備以下特徵"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代碼邏輯對於其他項目開發人員清晰簡單;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"清晰的代碼不包括拷貝重複項"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"乾淨的代碼包括極少的類和方法"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代碼測試覆蓋了100%"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"技術債務(why)"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"產生技術債務的原因"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"業務壓力,可能需求迭代的速度要求你必須迅速完成功能上線,而沒有時間去完成被忽略的優化工程"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你的上級或者僱主不理解技術債務具有“利益”,因爲隨着債務的累積,技術債務減慢了發展速度。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無法嚴格按照組件的一致性的規則。通俗的講就是每個功能的改變可能會影響到其他的組件。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺乏全面的測試"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個組成員之間缺少相互的交流和反饋"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺少清晰的文檔,這樣導致新來的員工不能很快的接手項目"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個長期項目存在多個分支同事開發,這樣導致了後期項目工程後的合併混亂"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重構項目遲遲被延期,無法進行"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"缺少合理定時的監控"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"技術開發員工甚至不知道如何或者是否需要重構"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":11,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"何時需要開始重構(How)"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三個規則"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當你實現一個功能的時候,只需要完成實現該項目工程,而不需要考慮後續的複用性"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"面臨做不願意重複的項目事情的時候,而不得不重複"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當你在做一個項目需要重複第三次的時候,這個時候請重構"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在添加新的功能的時候"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果您必須處理別人的髒代碼,請嘗試首先對其進行重構。乾淨的代碼更容易掌握。您不僅會爲自己而且還會爲在您之後使用它的人改進它。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重構後如何可以更容易的添加新功能,並且使得代碼更加清晰易懂"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當修復bug的時候"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"修復bug的時候,你會自己發現代碼中存在的可優化的項目"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當你的boss讚揚主動重構的行爲時"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在code review的時候"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"code review的時候也許是項目上線發版之前最後一次機會來清楚一些不必要以及不合理的代碼"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與代碼開發者一起評審的時候,這樣,您可以快速解決簡單的問題,並確定解決更困難的問題的時間"}]}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"如何重構"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"在重構之前,請先理解項目並羅列需要重構的清單"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請把代碼變得更加乾淨清晰:如果你重構後代碼仍然是代碼仍然是不乾淨,模糊不清,對是一些小改的時候,也許看來你是在浪費時間。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"新的功能函數不建議在重構中添加,否則你會將代碼重構的時候變得混亂"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以的測試必須覆蓋重構後100%代碼,需要注意的是你重構測試的時候,有兩種情況會導致你的測試崩潰:"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"重複期間不斷出現bug,然後繼續修復bug"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你所寫的test是比較低級的測試,而無法覆蓋一些特殊場景的測試"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"underline"},{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"重構的具體實現"},{"type":"text","text":"(detail)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"代碼組織"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"長方法"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"產生原因"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"很多情況,在原有的方法裏面添加功能比重現創建一個方法,重現的實現全套方法邏輯要簡單的多,因此在項目迭代過程中,我們都會在原來的方法裏面裏增加需要的功能內容"}]}]}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"解決方案"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果方法過長本身內容實現過長的時候,需要將方法裏的內容提取出來改成extraMethod方法,這樣通過方法調用方法"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果在抽取方法的時候,遇到一些當前作用域下的參數不好提取的時候,可以用查詢的方法替換臨時變量"}]}]}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"// 優化前\ndouble calculateTotal() {\n double basePrice = quantity * itemPrice;\n if (basePrice > 1000) {\n return basePrice * 0.95;\n }\n else {\n return basePrice * 0.98;\n }\n}\n\n// 優化後:\ndouble calculateTotal() {\n if (basePrice() > 1000) {\n return basePrice() * 0.95;\n }\n else {\n return basePrice() * 0.98;\n }\n}\ndouble basePrice() {\n return quantity * itemPrice;\n}\n"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果碰到方法參數過多的情況下,可以將入參組成一個結構體對象。"}]}]}]},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"\n// 優化前\nfuncDemo (int a,String b,double c,Mapd,List
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.