看到這條款有種水到渠成的快感, 來寫下心得。
在我大學寫 Java 四年的時光裡, 我寫了一堆 over design 假 OOP 的東西。於是, 在我出社會工作的三年裡, 我改用 Python 盡可能的都寫成 function, 覺得很卡時 (像是一堆參數重覆傳來傳去), 才會包成 class。想體會看看兩種極端的寫法, 藉此看看能否從中悟出什麼道理。
這七年的時光合起來, 我沒悟出什麼大道理, 到是覺得後來這種寫法偶而是有點不便, 不過大部份時候還挺順的, 不會包得太笨重。直到看到 Effective C++ item 23, 才有種恍然大悟的感覺, 明白背後的原因。
作者提出一個觀點: 愈少程式能動到資料, 封裝的效果愈好。所以, 若這個操作可以寫成 non-member、non-friend function, 可保證它不能存取到 private data。再者, 也比較有機會讓不同 class 來重用這個 function。像是 std 裡面的 sort(), 就比放到 vector 裡成為 member function 來得好。既可提高 vector 的封裝效果, 也方便重用 sort (有提供 index 和 comparable 即可)。這篇從兼顧「減少相依性」和「提高重用性」切入說明這則條款的精髓, 值得一讀。
初看這個觀點有些反直覺, 還是會覺得放到 class 裡比較像「封裝」。要找函式時也比較方便, 看 class 的 header 就可知道全部操作。但 item 23 接著強調: 若要方便找函式, 放在 namespace 下也有類似的效果, 如同 Java 寫成 utility class 的 static member function 一樣。
回想 Java 的 Arrays.sort() 和 Collections.sort() 也是同樣的設計, 只是 Java 沒 namespace, 這類函式改放到某個 class 下。當然, Python 的 sorted() 也是如此, 不過是放在 __builtin__ 這個 package 裡。其它類型的還有 max()、min() 等函式。Python 和 Java 都有提供方便的 max()、min() 來操作 container, 不知 C++ 有沒有類似的東西, 只看到 algorithm 有比較兩個數字的實作。
2011-11-22 Update
經 Aethanyc 提醒, STL 裡有 max_element() 。