Showing posts with label refactoring. Show all posts
Showing posts with label refactoring. Show all posts

Friday, November 04, 2005

Improving The Design of Existing Code

標題都這樣下了,當然要祭出《Refactoring》這部經典囉!

這本書問世到現在,重構已經是成熟的軟體技術了,對程式員來說,裡面的東西就如同空氣和水般,融入每天的編程中。

我只是手癢,上來把這部經典裡面的名句摘錄一番,日後也好隨時端詳端詳:

  • 如果你發現自己需要為程式添加一個特性,而程式碼結構使你無法很方便地那麼做,那就先重構那個程式,使特性的添加比較容易進行,然後再添加特性。
  • 重構之前,首先檢查自己是否有一套可靠的測試機制。這些測試必須有自我檢驗(self-checking)能力。
  • 重構技術係以微小的步伐修改程式。如果你犯下錯誤,很容易便可發現它。
  • 任何一個傻瓜都能寫出計算機可以理解的程式碼。唯有寫出人類容易理解的程式碼,才是優秀的程式員。
  • 重構(Refactoring)(名詞):對軟體內部結構的一種調整,目的是在不改變「軟體之可察行為」前提下,提高其可理解性,降低其修改成本。
  • 重構(Refactor)(動詞):使用一系列重構手法,在不改變「軟體之可察行為」前提下,調整其結構。
  • 事不過三,三則重構。(Three strikes and you refactor)
  • 不要過早發佈(published)介面。請修改你的程式碼擁有權政策,使重構更順暢。
  • 程式碼的壞味道。(Bad smells in Code)
    1. Duplicated Code
    2. Long Method
    3. Large Class
    4. Long Parameter List
    5. Divergent Change
    6. Shotgun Surgery
    7. Feature Envy
    8. Data Clumps
    9. Primitive Obsession
    10. Switch Statements
    11. Parallel Inheritance Hierarchies
    12. Lazy Class
    13. Speculative Generality
    14. Temporary Field
    15. Message Chains
    16. Middle Man
    17. Inappropriate Intimacy
    18. Alternative Class with Different Interfaces
    19. Incomplete Library Class
    20. Data Class
    21. Refused Bequest
    22. Comments
  • 當你感覺需要撰寫註釋,請先嘗試重構,試著讓所有註釋都變得多餘。
  • 確保所有測試都完全自動化,讓它們檢查自己的測試結果。
  • 一整組(a suit of)測試就是一個強大的臭蟲偵測器,能夠大大縮減搜尋臭蟲所需要的時間。
  • 頻繁地執行測試。每次編譯請把測試也考慮進去,每天至少執行每個測試一次。
  • 每當你接獲臭蟲提報(bug report),請先撰寫一個單元測試來揭發這隻臭蟲。
  • 編寫未臻完善的測試並實際執行,好過對完美測試的無盡等待。
  • 考慮可能出錯的邊界條件,把測試集中火力在那兒。
  • 當事情被大家認為應該出錯時,別忘了檢查彼時是否有異常如預期般地被拋出。
  • 不要因為「測試無法捕捉所有臭蟲」,就不撰寫測試碼,因為測試的確可以捕捉到大多數臭蟲。

Sunday, February 01, 2004

The Prolog Interpreter

這學期加入 AI 助教群,我打算讓學弟妹從實作中瞭解 Unification Algorithm ,但又不想為他們帶來太大的負擔。從眾多 Prolog language 的 open source 中,我選出了 Peter Bouthoorn 所開發的版本,它原本就是被用於教學,可惜其程式架構實在稱不上漂亮。在無法坐視不理下,我一次一小步地 refactor 它,改了幾百個回合,並將其中好幾個關鍵的地方整個重寫,才有一個適用的 Prolog Interpreter 。這真是個不錯的練習。

接下來是將這個動過手術的 Prolog Interpreter 版本當中的 Unify, OccrCheck, and UnifyVar 等 functions 挖空,要學弟妹參照 AI 課本的 Unification Algorithm 後,為這些挖空的 functions 補上血肉。

考慮到修課的人數眾多,為了讓自己在批改作業時不會哭出來,必定得把這個作業批改的流程盡量自動化。

於是我就為學弟妹準備了一對 .txt 檔: input.txt 及對應的 output.txt 。為了怕有些學弟妹過份聰明地以 printf 將 desired output 直接印出,在批改作業時另外準備其他 input 及 desired output是一定要的。這部分我以 Unit Test 的工具來自動比對,只有在比對出錯才要告訴我出錯的地方在哪,否則它只要簡單打個點代表程式還活著,並在通過所有測試後吐出 OK 就好了。

為了更省事,我在 Windows XP 下裝了 MinGW with MSYS 來模擬 Linux 的 terminal ,並寫了一個 BASH 的 script 來將這一百餘份程式作業自動作執行、比對及歸類的動作。

Unit Test tool 在 Java 下有 JUnit 可以用,無奈這裡用於開發的程式語言是 C++ ,所以勢必要另外找一套對應的工具。我最先注意到的是其中最有名的,移植自 JUnit 的 CppUnit ,進一步瞭解後,發現它 Java 味太重了,感覺很不純,而顯得有點礙手礙腳(唉呀,我是不是太偏執了),於是我最後選擇使用專為 C++ 打造的 Unit++ 。嗯,這次用起來果然很順手 ^___^