l

2014年4月9日 星期三

談談壞味道(2):Long Method & Large Class

Mar. 21 15:40~16:51

螢幕截圖 2014-03-21 17.30.27

Short method比long method好。

 

Long Method(過長函數)

在〈什麼是Refactoring?〉提到long method的三個force,今天來解釋一下這三個force的含意:

  • Explanation(解釋):透過閱讀程式去理解軟體設計是一種常見的方式,而每一個method都有一個名字用來代表這個method的意圖。如果method內容很長,可能意味著這個method做了太多事,也就是說method的名稱很可能無法清楚解釋method的內容。廣義的說,long method降低understandability。
  • Sharing(共享):long method的某一段程式也許在其他地方可以被重複使用,但因為long method包含太多其他東西,因此排除了別重複使用的機會。sharing也可以看成是reusability。
  • Choosing(選擇):這一點看不懂什麼意思,知道的鄉民歡迎告知。

 

以上三點第三點choosing不知道什麼意思,先排除在force清單之中,另外Teddy還要追加兩點:

  • Modifiability(可修改性):long method程式碼較多,邏輯與狀態也相對比較複雜,因此要針對long method進行修改就變得比較困難,也比較容易出錯。
  • Testability(可測性):理由同上,因為long method程式碼較多,邏輯與狀態也相對比較複雜,所以也比較難進行測試。

為了統一force的用語,最後把long method之所以會是一個bad smell的原因(force)歸類為:understandability、modifiability、testability、reusability這四點。

***

移除long method壞味道的方法,在《Refactoring》書中提到可以套用Extract Method、Replace Temp with Query、Introduce Parameter Object、Preserve Whole Object、Replace Method with Method Object、與Decompose Conditional。

***

Large Class(過大類別)

Large class和long method壞味道很像,都可能造成duplicated code以及降低重複使用的可能性。只不過long method關注的點在method層次,而large class則是在class層次。

一個large class可能會擁有太多的instance variable,這些instance variable可能在某些狀態下才有作用,或是只被某些特定method使用。這都是一種「內聚力不強」,或是說類別負擔過多責任的徵狀。同樣地,如果類別擁有太多的method,也很有可能是一種負擔過多責任的徵狀。

Large class之所以會是一個bad smell的原因(force)和long method一樣,可歸類為:understandability、modifiability、testability、reusability這四點。只不過因為large class的scope比較大,因此這四點force對整個系統所造成的影響比單一的long method還要來的強烈。

***

移除large class壞味道的方法,在《Refactoring》書中提到可以套用Extract Class、Extract Subclass、Extract Interface、Duplicate Observed Data。

***

友藏內心獨白:怎麼都是一些non-functional requirement。

2 則留言:

  1. choosing 是否有可能為選擇「實作方式」呢?分離至許多short method後,各個method內的行為就被切割開了,若是需要單獨改變某個short method內的行為時,不需修改整個long method?就像是Teddy追加兩點說明的另一種說法?

    回覆刪除
  2. 所謂的"過大"、"過長",標準在哪?我覺得應該是相對而言,在整個程式內,好比說平均一般Function大概是20行,如果你有一個Function寫了一千行,那這個Function極有可能是你需要重構的對象,接著隨著你一次次重構,平均行數變短,你再依新的標準找尋需要重構的Function/class,循序漸進的重構你的程式。

    回覆刪除