程式者的胡言亂語
程式碼共有下的團隊開發
設想一個情境,和你一同開發某個系統的同事請假了,不幸的是,這個系統臨時發生了一個嚴重的問題,必須在最短的時間內修正問題,但這位同事卻是無論如何也無法連絡的上,此時該當如何?倘若出了問題的所在,只有這個同事才了解詳情,其餘的同事即便手上能存取這段出了問題的程式碼,面對錯綜複雜的程式碼,不見得能在短時間理解,冒然的動手修改,一來不見得能解決問題,二來就算能解決眼前的燃眉之急,由於軟體的高度複雜性,也很有可能引發意料之外的副作用。
這樣的情況其實在我們的開發生活中偶而發生,而這樣困境其實導因自常見的開發方式。或許你的團隊也是這樣,進行完系統分析、完成了系統設計,接著專案經理將撰寫程式碼的工作以某種單位拆解,然後分派給團隊中的每一個成員。這是相當常見的工作分派方式,我們常常會聽到:「XXX你負責這幾支程式,而XXX你則負責另外那幾支程式。」之類的話,便是屬於這一種模式。程式碼是以「支」為單位,而每個人的程式碼編寫工作之間很少會有交集,大家分頭進行,各自埋首完成自己的目標。只有當程式與程式之間需要相互整合時,你才會和你那些一同為了開發專案目標而努力的伙伴們有較為頻繁的互動。但即便如此,每個人多半還是在介面層次上進行整合,因而將對方的程式模組視為是黑箱,也不會細究其中的內容。當團隊成員對彼此程式碼的冷漠及陌生時,就會衍生出上述的問題。
除了臨時救火之外,軟體開發團隊難免遇上人員流動的情況。只要發生了人員流動,多半就會衍生出交接的情況,而這所謂的交接,實際上時常只是形式上的交接。辦理交接的人員,很難在極短的交接時間內,真正的了解他所交接而來的程式碼細節處究竟是如何構成及運作的。
面對上述的問題,極限編程(eXtreme Programming,XP)提出了一個稱為「集體程式碼共有(Collective code ownership)」的概念。在這個概念下,專案中的每個人都有權力、以及能力,基於增加功能、修正錯誤、以及重構的原因,更動系統中的每一行程式碼。系統中的某一程式碼片段,不再隸屬於特定的一位程式員,也不再只是「XXX負責的那一支程式」。每個人都應該能夠輕易的讀懂系統中的每一段程式碼,明白這段程式碼究竟是如何運作,知道如何為它添加新功能、如何加以修正、重構而不致於引發意外的錯誤。在程式碼共有的團隊中,發生了緊急的問題時,每個團隊成員都具備能力處理。即使發生了人員流動的情況,其他人也很容易替補上他原有的工作。
這聽起來真像是開發團隊理想中的大同世界呀。
這樣的想法,和傳統上我們所習以為常的模式大相逕庭。而這樣子的概念想要於實務上落實,也會需要克服不少的挑戰。在極限編程中,利用許多其他的實踐準則來搭配,才有可能達到這個理想的目標。例如,透過搭檔編程(pair programming),時常的變換一起搭檔撰寫程式的伙伴,使得每個人具有更多的機會接觸系統中各個面向上的程式碼。
此外,透過建立系統的隱喻(system metaphor),讓團隊的成員能以一致的規則來為類別、函式、變數等等命名。隱喻最大的作用,在於讓團隊中的成員能夠操弄同一套語言以及詞彙,使得程式員們能夠輕易的望文生義。這套語言及詞彙不僅只是共通的命名慣例,更會使得許多特定用語有著特定的意義。例如,設計模式就是一組隱喻,當你看到了名稱中帶有“Factory”、”Proxy”等詞的類別時,你會立即明白它們的作用,而不需要額外多做太多的說明,這正是隱喻的作用所在,能夠大大的減少溝通的時間,也降低發生誤解的情況。程式碼本身將更能自我說明(self-documented)。
當然,除了系統隱喻之外,程式碼撰寫時的標準也是同等的重要。所有的團隊成員都必須依循相同的程式碼風格寫作規範(例如編排的程式碼準則),這麼一來,每個團隊成員才能無障礙的閱讀以及修改。
XP更主張設計要簡化,盡可能的簡化程式碼降低複雜程度,這能提昇程式碼的易讀性,不容易造成誤解,當然有助於程式碼成為共有。
XP將此稱為共同認識(Shared understanding)。XP透過上述的準則將程式碼與開發成員的一對一關係,擴大成為多對多的關係,一段程式碼不再為單一個開發者所獨攬,所以這位開發者不再成為這段程式碼的瓶頸。程式碼成了團隊所有成員所共有,對於系統程式碼的認識會動態而且持續的在團隊中流動。
雖然並非每個團隊都適合或是打算實施XP的方式,但XP的這些實踐準則卻是給了我們很好的指引。即使我們不採用XP的開發方法,我們仍然可以藉由XP的實踐準則來提昇程式碼的共有程度。
對於程式碼,程式員普遍不習慣共有,程式員們也排斥去修改、甚至是閱讀其他人所撰寫的程式碼。但推行程式碼共有好處實在不少,除了可以解決上述提到的維護問題以及人力銜接的問題之外,它也提供一個機會讓程式員之間的知識及技巧能夠在團隊中流動,而這一點對團隊帶來的助益甚大,因為這樣的做法讓成員間彼此有更多的機會見識到其他人所撰寫的程式碼並且動手實際操弄。你有更多的機會見識到其他成員是如何的解決問題。這是真正的學習,不僅僅只是那種來自課堂上或從書本上的學習所得,而是親眼見到其他高竿的傢伙是如何運用自己所不知或不熟悉的方法及技巧來解決自己同樣遭遇到的問題。
在多年以來,我所參與的團隊主張,讓每個成員寫出一致風格的程式碼,我們的目標便是讓每一段程式碼看起來都分不清楚究竟是誰所撰寫的。也只有達到像這樣子的目標,才能夠讓每一段程式碼看起來都像是自己寫的。雖然我們沒有實施搭檔編程,但諸如建立系統隱喻、相同的程式碼風格寫作規範、以及簡化設計等XP所揭櫫的其餘準則,都讓我們在邁向程式碼共有時,得到相當大的助益。即使沒有因為實施搭檔編程,而喪失了讓每個人實際接觸到每一段程式碼的機會,但是由於實施了其他的做法,使得每個人很容易在很短的時間了解別人所撰寫的程式碼,並且不易發生誤解,使得功能的修改或擴充做起來都格外的簡單。我們會交互的去修改別人所撰寫的程式碼或是加以擴充,雖然比不上搭檔編程,但也能達到不錯的效果。而在這過程中,新加入的成員得以透過觀摩舊有成員們的既有程式碼,迅速的融入團隊的文化中,也能透過觀摩學習到自己所不知的技巧及設計方式。最好的學習就是從模倣開始。模倣舊有成員的做法,可以讓新成員更快上手,也學習的更快更有效。即使在這些年中人們來來去去,但我們始終沒有因為人員的變化而發生什麼交接上的問題。
如果你的開發專案沒有程式碼權限控管的問題,那麼推行程式碼的共有,肯定能為你的團隊帶來益處。
Blogged with Flock
Posted at 06:22下午 七月 23, 2008 by Chien-Hsing Wang in General | 迴響[6]
星期三 七月 23, 2008

頭香!
Q大寫得太好了,馬上轉寄給主管看...
由...發表 鳥毅 on 七月 24, 2008 at 11:02 上午 CST #
版大:您有提過會出Thanking in Java新刷版,請問何時能拜讀您的大作?小弟已經等很久了,感謝~
由...發表 arliang on 七月 25, 2008 at 11:50 上午 CST #
Hello, arliang,
本書應該已經送印了 :)
由...發表 Qing on 七月 25, 2008 at 01:34 下午 CST #
寫的太好了, 深得我心, 一直也試著在公司內推動類似的東西, 開始有點沒方向, 因為XP對我們來說, 還是有太多的障礙點了, 現在我有個目標了...
由...發表 bFish on 七月 25, 2008 at 10:47 下午 CST #
非常棒的文章,忍不住 forward 給研發同仁了 :)
由...發表 Drake on 七月 27, 2008 at 12:59 下午 CST #
我對 XP 的相關開發流程方法也很感興趣。
不知道國內是否有公司或者團隊,是真的遵循著 XP 的流程進行專案開發?
還有就是 Test-Driven Development 這個東西,
看起來是個好物,不過在我認識的人裡從來沒聽過真實的使用案例。 Orz
由...發表 半路 on 八月 06, 2008 at 02:21 下午 CST #