Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Code refactoring using eclipse

2,263 views

Published on

Code refactoring using eclipse

  1. 1. 用 Eclipse 重構程式碼Code Refactoring Using Eclipse 中華電信 黃培棠 beta@cht.com.tw 2013/02/26
  2. 2. WHAT IS REFACTORING? 2
  3. 3. 2 𝑥 − 1 = 𝑥 + 1 (𝑥 − 1) Factoring: 因式分解參考資料: http://zh.wikipedia.org/zh-tw/代碼重構 3
  4. 4. 2 𝑥 −1 不影響外部行為 2 = 𝑥 − 𝑥+ 𝑥−1 = 𝑥 𝑥−1 + 𝑥−1 = 𝑥 + 1 (𝑥 − 1)循序漸進, Re- 4
  5. 5. 怎麼證明?• Given f x = 𝑥 2 − 1 – We know that f 3 = 8• 單元測試 3A 原則: – Arrange: f 3 = 8, f′ x = 𝑥 + 1 𝑥 − 1 – Act: f ′ 3 = 3 + 1 3 − 1 = 4 × 2 = 8 – Assert: f 3 = f ′ (3) 數學家看了可能會搖頭, 還好我們是 Programmer! 5
  6. 6. 重構前… 重構後… 重構是 Programmer 自爽的事? 6
  7. 7. Refactoring 定義 • Refactoring (名詞) – A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior. • 除非你想參加 OMG WTF http://thedailywtf.com/Articles/The-Worse-Than-Failure-Programming-Contest.aspx“Refactoring: Improving the Design of Existing Code”, Martin Fowler, Kent Beck, et al., 1999 7
  8. 8. Any fool can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler“Refactoring: Improving the Design of Existing Code”, Martin Fowler, Kent Beck, et al., 1999 8
  9. 9. WHEN TO REFACTORING? 9
  10. 10. 重構的好時機• 一樣的事做到第三次時• 按下「貼上」前• 要新增功能時• 開始修 Bug 前• Code Review 時 10
  11. 11. If it stinks, change it. —Grandma Beck, discussing child-rearing philosophy“Refactoring: Improving the Design of Existing Code”, Martin Fowler, Kent Beck, et al., 1999 11
  12. 12. 重構標的 — Code Smells Within Classes Between Classes • Comments • Primitive Obsession • Long Method • Data Clumps • Long Parameter List • Refused Bequest • Duplicated Code • Indecent Exposure • Conditional Complexity • Feature Envy • Large Class • Lazy Class • Uncommunicative Name • Divergent Change • Dead Code • Shotgun Surgery • … • …http://www.codinghorror.com/blog/2006/05/code-smells.html, Coding Horror: Code Smells, May 18. 2006 12
  13. 13. 怎麼跟老闆講?• 不用講,做就對了• 重視品質的老闆 – 他會懂你的• 嘴巴說重視品質的老闆 – 說了也是白說 – 你真的是在幫他 – The fastest way is to refactor; therefore I refactor. – Martin Fowler 13
  14. 14. 什麼時候該停手 • 程式該砍掉重練時 // When I wrote this, only God and I understood what I was doing // Now, God only knows • Deadline 前夕 • 夠好了,對你自己、客戶、還有下個_____ – 明天會更好 – Striving to better, oft we mar what’s well. – “King Lear” 1.4, William Shakespeare – Good-Enough Software, “The Pragmatic Programmer”, Andy Hunt, David Thomashttp://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered 14
  15. 15. REFACTORING USING ECLIPSE 15
  16. 16. Coding Style• 確定團隊整體的 Code Style Formatter – 養成常 [Ctrl] + [Shift] + [F] 的習慣• 輔助確認格式 – 以 eclipse-cs 輔助確認 • 同樣要先定義好 Checkstyle 的 Rule – 統一使用 AnyEdit Tools 外掛程式 – 在版本管理系統上面掛 pre-commit hook 16
  17. 17. 移除 Dead Code • // Don’t do this! // There was a time, back in the sixties, when // commenting-out code might have been useful. • // Nowadays, just delete the code // We won’t lose it. Promise. // Revision control system will remember it.“Clean Code: A Handbook of Agile Software Craftsmanship”, Robert C. Martin, August 2008 17
  18. 18. 移除 Dead Code • Visibility 要盡可能低 – public > protected > package private > private public void whyNoOneCallsMe() { // Why am I so useless, how can I not be? } private void whyNoOneCallsMe() { // Why am I so useless, how can I not be? }http://sourcemaking.com/implementation-patterns/method-visibility, Method Visibility 18
  19. 19. Dead Code 移除小技巧• 注意 Reduce Visibility 可能的風險 – 介面已經昭告天下時只能 @Deprecated• Dead Code 不見得都那麼好發現 – 不可能跑到的 if else 或 switch case 區塊 – 請 PMD, FindBugs 幫忙• 開始用其他重構技巧吧! – 讓原本的程式更好懂、好修改。 19
  20. 20. Eclipse 1.0 (Nov 2001)圖片提供: https://twitter.com/jiayun 20
  21. 21. Eclipse 2.0 (Jun 2002)圖片提供: https://twitter.com/jiayun 21
  22. 22. Eclipse 2.1 (Mar 2003)圖片提供: https://twitter.com/jiayun 22
  23. 23. Eclipse 3.7 (Jun 2011) 圖片提供: https://twitter.com/jiayun 23
  24. 24. Rename• 使用時機 – 看到不順眼或是無法會意的名字 – 有病治病,沒病強身• 命名原則 – 簡單明瞭 – 符合 Naming Convention (由 Coding Style 規範) • 例如: getRgbHex(Colors.SNOW_WHITE) 24
  25. 25. Rename 注意事項• 要保留住檔案修訂歷程 – 裝好 Eclipse Team Provider 再改名 – 否則請用 SCM Client 提供的改名功能 25
  26. 26. Rename 小技巧• 開 Mark Occurrences 功能 OutputStream os = new FileOutputStream("test.txt"); try { os.write("test".getBytes()); } finally { os.close(); }• Method 改名可用 Change Method Signature – 如果介面已經公開,請勾 “Keep original method as delegate to changed method” 選項 26
  27. 27. 改名參數名稱、順序也能改 維護 相容性 27
  28. 28. Extract Local Variable• 使用時機 – 一行程式串太長 new BufferedOutputStream( new FileOutputStream("test.txt")); – 發現對同一個資料物件重複取值 authorties = repository.queryAuthorities(user.getName()); LOGGER.debug("User {} authenticated.", user.getName()); 28
  29. 29. Eclipse 會幫你做的事 重構 結果 29
  30. 30. Extract Local Variable 注意事項 • Variable 的 Scope 一樣是越小越好 – 一般就是 Local Variable 被 Extract 出來的位置 – 使用 [Alt] + [↑]/[↓] 可以調整 int value = getTheAnswerToTheUltimateQuestion(); Result result = new Result(); // <= 要用到再宣告 result.setValue(value); return result; • Extract 過頭怎麼辦? – Inline 是 Extract Local Variable 的 inverse。http://www.refactoring.com/catalog/reduceScopeOfVariable.html, Reduce Scope of Variable 30
  31. 31. Extract Local Variable 偷吃步• 宣告變數並給值少打字 – 直接寫右邊的內容 – 讓 Eclipse 幫你把左邊的宣告補起來 encrypt(data, certificate); [Alt] + [Shift] + [L] EncyptionResult result = encrypt(data, certificate); 31
  32. 32. Extract Method• 使用時機 – Method 內容過長,超過螢幕能顯示的範圍 – 很想幫 Method 裡某個區塊加註解時• Method 設計原則 – 名稱符合 Coding Style – 參數數量不要太多或是型別重複 32
  33. 33. // 取憑證X509Certificate certificate;try { String base64Cert = certificateRepository.queryMoicaCertificate user.getUserId(), user.getName(), user.getCounty()); certificate = CertificateUtils.generateCertificate(base64Cert);} catch (CmsException e) { throw new CmsEncryptionException(e.getMessage(), e);}// 資料加密EncyptionResult result = encrypt(data, certificate); // 取憑證X509Certificate certificate = retrieveCertificates(user);// 資料加密EncyptionResult result = encrypt(data, certificate); 33
  34. 34. Method 參數長相是關鍵• 先 Extract Local Variable,讓 Method 更精確 notifyUser(User user); String userId = user.getId(); notifyUser(String userId);• 往前多選到 Variable,讓新 Method 更簡單 String userId = user.getId(); notifyUser(String userId); notifyUser(User user); 34
  35. 35. Extract Method 偷吃步• Method 規畫方式 1. 能先想清楚最好 2. 不然先定義參數物件,再慢慢修改其 Property 3. 如果剛好今天沒帶腦,就先寫成一坨,再 Extract Method 出來• 使用大忌: 不要為了 Extract 而 Extract – 雖然犯錯了一樣可以 Inline 回去 35
  36. 36. Extract Interface • 使用時機 – 發現兩個物件的行為有點像時 – 很謙虛,不想暴露太多面向的資訊給使用端時 – 有特別的情感因素時http://sourcemaking.com/refactoring/extract-interface, Extract Interface 36
  37. 37. Extract Interface 注意事項• 使用 Interface 好處多,不過也是有代價的 – 現在 Spring Framework, Mockito… 都能簡單處理 Class,不是非 Interface 不可• 不用先定義好 Interface – 除非你正在設計要公開的 API – 用到再做都還不遲 37
  38. 38. 繼承結構調整• Extract Superclass – 跟 Extract Interface 有點像,但是包含 Filed 及 Method 實作• Pull Up – 將 Member 往上層提 (Generalization)• Push Down – 跟 Pull Up 相反 (Specialization) 38
  39. 39. 繼承結構調整 注意事項• 不是什麼都該繼承來 – 有時候用別人家的更划算! (改用 Composite) – 想清楚到底是 Is-A 或是 Has-A 39
  40. 40. Introduce Parameter Object• 使用時機 – Method 參數過多 (4, 5 個就算不少了) – Method 參數中有相同的型別• 範例: getColorName(int red, int green, int blue); getColorName(Color color); color.getName() 40
  41. 41. Extract Class• 跟 Introduce Parameter Object 異曲同工• Extract Class 的對象是 Class 裡的 Field public class Employee { private String name; private String officeAreaCode; private String officeNumber; } public class Employee { private String name; private PhoneNumber officeTel; } public class PhoneNumber { private String areaCode; private String number; 41 }
  42. 42. Extract Class 小技巧• 同時選取多個 Class 可以提出共用的 Fieldpublic class Employee { public class Outsourcer { private String name; private String contractId; private String officeAreaCode; private String officeAreaCode; private String officeNumber; private String officeNumber;} }public class Employee { public class Outsourcer { private String name; private String contractId; private PhoneNumber officeTel; private PhoneNumber officeTel;} } public class PhoneNumber { private String areaCode; private String number; } 42
  43. 43. Try to leave this worlda little better than you found it. – Baden-Powell 43
  44. 44. REFERENCES 44
  45. 45. 參考資料• “Refactoring: Improving The Design of Existing code”, Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts, 1999• Code Smells - Jeff Atwood – http://www.codinghorror.com/blog/2006/05/code- smells.html• Web 程式重構 – Jace Ju – http://www.slideshare.net/jaceju/web-1494836 45
  46. 46. 延伸閱讀• 如何成為更好的 PHP 開發者 – Jace Ju – https://speakerdeck.com/jaceju/how-to-be-a-better- php-developer• 27 inspiring top notch programming quotes – http://www.marcofolio.net/tips/27_inspiring_top_n otch_programming_quotes.html 46
  47. 47. 可參考的書籍• “Refactoring: Improving The Design of Existing code”, Martin Fowler, Kent Beck, John Brant, William Opdyke, and Don Roberts, 1999 – 《重構 – 改善既有程式的設計 第二版》 侯捷、熊節 譯 – http://sourcemaking.com/refactoring• “Refactoring to Pattterns”, Joshua Kerievsky, 2004 – 《重構 – 向範式前進》侯捷、陳裕城 譯• “Java言語で学ぶ リファクタリング入門”, 結城 浩, 2007 – 《Java 重構》江珮齡、王元綱、博碩文化 譯 47

×