4

Implementation Patterns: Composed Method

 2 years ago
source link: http://teddy-chen-tw.blogspot.com/2012/05/implementation-patterns-composed-method.html?showComment=1632552524653
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Implementation Patterns: Composed Method

May 20 22:23~22:42

今天沒什麼廢話,直接進入主題。今天要繼續介紹Kent Beck所寫的Implementation Patterns這本書的第77-78頁所介紹的Composed Method這個implementation pattern。

有寫過程式的鄉民們應該都知道,在寫程式的時候,每一個函數(function)或是方法(method)的內容寫法,不外乎有以下三大類:

  • 全部的程式邏輯都直接寫在method body裡面,例如下面這個add method的邏輯,:

int add(int x, int y){

     return x + y;

  • method的實作式全部都是藉由呼叫其他的methods來達成,例如:

void doSomething() {

      readInput();

      process();

      output();

  • method的實作包含部分直接寫在method body裡面的邏輯,以及部分呼叫其他的methods來達成,例如:

void addChild(Object childNode) {

       if (atCapacity())
                grow();

        addElement(childNode);

依據Kent Beck的說法,Composed Method的有兩個要求:

  • 藉由呼叫其他method來完成自己的工作。
  • 在Composed Method內部的每一個操作(operation)與被Composed Method所呼叫的每一個method必須要有差不多大小的抽象程度。

從上面這兩點來看,add()顯然不是一個Composed Method,而doSomething()和addChile()則屬於Composed Method。

So what?看到這邊鄉民們可能會這樣想,這有什麼了不起的,程式不就是這樣寫的,把實作寫在自己身上,或是呼叫其他人,或是兩者混和。既然這本書的目的是希望能寫出容易理解的程式,當然Kent Beck提出Composed Method這個pattern一定有一些學問在裡面。看一下書本中的例子:

void compute() {

input();

flags |= 0x0080;

output();

不曉得鄉民們有沒有寫過或是看過類似的程式?Teddy倒是經常看到。上面這個compute()的寫法,看起來像是一個Composed Method,但是這是一個寫得不好的Composed Method。為什麼?因為違反了Composed Method的第二條規則:「在Composed Method內部的每一個操作(operation)與被Composed Method所呼叫的每一個method必須要有差不多大小的抽象程度」。compute()一共只有三行程式,很明顯的input()與output()的抽象程度是類似的,但是這個第二行的 flag |= 0x0080 是怎麼一回事,和其他兩行的程式邏輯抽象程度也未免相差太多了吧。這樣的Composed Method顯然不易閱讀也不易理解。

把一個(內容很長的)method的內部邏輯依據功能或是目的,分別抽離出來變成若干個小methods(可參考Extract Method這個refactoring),然後在原本的method中去呼叫這些被抽離出的methods,那麼原本的method就變成Composed Method。接著鄉民可能會問以下幾個問題:

  • 被抽離出來的method要有多長:這個問題其實沒有什麼正確的答案,有人說method長度列印出來之後不要超過一頁(A4或是Letter size),或是一個method不要超過5-15行(好嚴格啊)。
  • Composed Method內部呼叫太多很小的methods,這樣不會對程式效能造成影響嗎:會,當然會有影響。Kent Beck做了一個小測試,呼叫某個method一百萬次,比直接在迴圈中執行該method的內容平均大概慢20-30%。Kent Beck認為這樣的效能差距不足引影響大部分的程式。此外,幾乎所有物件導向大師都會告訴你,有一個結構清楚的程式,反倒比較容易在效能測試中找出系統的瓶頸並加以改善。
  • 有時候某個method的內容包含了很多細節,這些細節有助於了解這段程式碼,但是卻不容易切割成抽象程度大小差不多的methods。該怎麼辦:答案也很簡單,套用另外一個叫做Method Object的pattern(這個pattern改天再介紹)。

相信只要有寫過程式的鄉民,一定都寫過Composed Method。至於Composed Method是否容易被理解,重點就在於有沒有讓Composed Method內部的每個operation都有差不多大小的抽象程度。這是Teddy覺得讀完這個pattern最大的收穫。

友藏內心獨白:小東西也隱含著大學問。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK