在程式設計上談到帽子,開發者會想到什麼呢?多半會先想到的大概是黑帽、白帽、灰帽,在考量安全問題時,戴上黑帽、白帽或者是灰帽,從不同角色的方向出發,往往能挖掘許多防護上的考量。

實際上,不單只是安全,開發時若也能有多頂帽子替換,在執行特定任務時,許多想法與做法的靈感,就能源源不斷地出現,連帶地,成果也會是確實而有用的。

從兩頂帽子開始

除了安全上的黑帽、白帽、灰帽之外,Kent Beck的兩頂帽子,也許最廣為開發者知曉。在Martin Fowler的《重構:改善既有程式的設計》中,就使用了這個比喻--開發者會添加新功能,有時會整理一下程式碼,以便有益於新功能的增加,這時該戴上重構的帽子執行任務,在重構任務完成之後,才能換上添加新功能帽子,繼續擴展程式。

那麼,換帽子的目的是什麼?書中談到:「把自己的時間分配給兩種截然不同的行為」。這確實是目的之一,程式開發過程中,新功能的增加、程式碼的整理,本就是交互穿插不息的過程,明確地將這些過程區隔開來是件好事,而且,戴上某個帽子的目的沒有達成之前,都不該中途停下,換上另一個帽子。

《重構》書中針對添加新功能的作法,談到:「不應該修改既有程式碼,只管添加新功能」,相對來說,如果新功能程式碼寫到一半,發現必須整理一下程式碼,才能繼續增加新功能,這時不應該立即換上重構的帽子,這往往會讓程式碼出現混亂,真正要做的,是先退回已寫的那一半程式碼,換上帽子完成重構任務之後,再重新施行新功能的添加。

也許,更重要的是換帽子的第二個目的:「找出接下來真正該做的任務。」在戴上某頂帽子完成任務之後,都應該思考:「接下來是要戴著同樣的帽子呢?還是要換頂帽子呢?」

也許你仍然決定繼續戴著添加新功能的帽子,這時就要認真思考一下,接下來可以實現什麼樣的新功能;或者你決定換上重構的帽子,這時就可以使用《重構》中談到的一些提示,嗅嗅看程式碼中是否有餿味(Bad smell)。

當開始將「找出接下來真正該做的任務」視為換帽子的重點時,也許就不再只會有兩頂帽子了,因為,如果接下來想到的,是該寫個有用的測試,那就有三頂帽子可以替換了。

不過,當戴上測試的帽子時,就該從測試者的角度來看,別去想另外兩個帽子會怎麼做,這樣就會有許多該怎麼測試的靈感產生了。

換個帽子換個腦袋

其實,換帽子就是換腦袋的意思,如果不知道該做什麼重構,換上重構帽子就是個強烈的暗喻:「有人要來閱審(Review)你的程式碼了」這時,他會看到什麼?只有戴著重構帽子時看到了問題,才會知道接下來要進行什麼樣的重構。

如果今天寫的是程式庫,那麼該有哪些特性考量呢?例如,剛剛有個旋轉座標的函式寫完了,換上使用者的帽子、試著使用函式:「嗯?為什麼這邊程式出現了錯誤?我輸入了座標與角度啊?」想像一下使用者做了臭蟲提報,接著,換回開發者的帽子,檢視了剛剛傳入的引數:「喔!這是二維座標,函式預期必須是三維座標。」這時,開發者應該會怎麼做呢?

換上使用者的帽子,暗喻著你是程式庫的使用者了,既然你會輸入二維座標,表示其他使用者也可能會這麼做,因此,換回開發者帽子之後,不該對著之前戴著使用者帽子的自己說:「使用二維座標是錯的,這個函式只接受三維座標」。使用者不該關心這種事,開發者應該做的,是判斷是否輸入了二維座標,若真是如此,就自動補上第三個預設為某個值的維度。

類似地,程式庫是否需要考量與內建函式的相容性?需要留下哪些參數?預設值與順序?API的組合性是否有足夠的彈性?這應該是個公開API,還是私有API?甚至於效能上是否能被接受,或者需要改進,當你換上對應的使用者帽子之後,往往就能找到答案。

不知道什麼樣的程式碼具有可讀性嗎?那麼,該戴上維護者的帽子,來看看這些程式碼中的變數、函式等命名,是否夠清晰?排版是否適當?如果是在某些日子之後,為了某個任務必須得回頭看看程式碼,而你需要花時間看完某段程式碼,才能知道它的目的是什麼,這也許表示它可能需要註解了,或者是重構成一個有適當名稱的函式。

什麼時候需要將程式碼送進版本控制系統?也許這是個很容易決定的時間點!在每次某個帽子任務完成的時候,因為可能是戴著不同角色的帽子完成不同的任務,因此,提交訊息時,也會是戴著不同帽子的角色所提交,就算這只是一人專案,提交訊息也會是看來像是很多人參與那樣的熱鬧。

不只是程式碼

不見得只是在面對程式碼時,才會需要換帽子,在執行某個任務時,若不知該怎麼做,換上適當的帽子之後,總是能帶來想法,就算是面對開發者覺得最枯燥麻煩的API文件,只要「確實地」換上文件使用者的帽子,就能知道使用者會想在文件中看到什麼樣的格式、參數說明的詳細程度、需要參考的外部鏈結,甚至是需要有什麼樣的範例程式碼。

注意!必須要「確實地」換上文件使用者帽子,此時,別再去想著文件撰寫者的帽子。如果戴著文件撰寫者的帽子,甚至是還是戴著程式庫開發者的帽子,卻想著要有什麼樣的範例程式碼,那就會因為帶著這些角色內心的枯燥,寫出一個某天回頭來重看,連自己都會覺得是雞肋的範例。

因此,在戴著文件使用者帽子之時,應該將想要看到的範例效果記錄下來,再重新戴上文件撰寫者的帽子,確實地把範例實現出來。

而且,面對一些問題時,若不試著換上另一頂帽子,以搪塞(workaround)方式來處理問題的情況,就會發生,然後,基於搪塞而產生的解決方案也會越來越多,最後難以收拾。

最近的一次慘痛教訓是,因為使用者可以另行使用軟體來修補解決破圖問題(當然,這很不方便),我就一直遲遲沒找出某基礎模組有時會產生破圖的真正原因,直到在官方文件中找到問題解答之時,基於該模組而衍生出來的模組已經有十幾個了,從頭修補起來也就極為費力了。

類似地,需要自動化嗎?又有哪些問題需要自動化?需要使用者介面嗎?什麼樣的介面才具有易用性?試著換上另一頂帽子來考量吧!

清楚自己戴的是哪頂帽子

在軟體開發上,有Pair programming的方法,實際上就是在開發過程中,能有戴著driver與navigator兩頂帽子的人同時存在,以便同時以不同的角度來考量眼前的任務,兩個開發者也不是一直戴著同一頂帽子,driver與navigator的角色也會經常互調。

就如同在《重構》中談到的:「無論何時你都應該清楚自己戴的是哪一頂帽子,」這點會是最重要的。如果戴著A帽子,心中想的卻是B帽子的事,那麼,B帽子的內心戲,就會影響到A帽子的任務而草草了事,而且,不管是可讀性、彈性、效能、安全、易用性、文件等,最後多半也會是徒具形式,或者是剩下一個半途而廢的爛攤子吧!

專欄作者

熱門新聞

Advertisement