在前文中,我們討論了我朋友 Larry 公司的大型重構專案:「系統 2.0 專案」的運作始末,並用 Release 規模的大小來討論可能更能避險的方法。今天我們從另一個角度來分析同一個主題:「團隊拆分」。
在 Larry 的故事中,他們公司看起來很明顯是用產品的「元件」來拆分。如果我們用 Winston Royce 的 Waterfall 模型來看(如下圖),也就是圖中每個方格都是不同 Team,甚至,一個方格又再細分成好幾個 Team,例如 CODING,看起來就至少分了「前端」「後端」「DBA」三個 Team,照這邏輯看起來,其他部份所需的 Team 數應該只會更多,而不會更少。
Winston Royce 的瀑布模型,圖片截自論文:Managing the Development of Large Software Systems
光就「開發」的功能來說,這間公司就拆分成三個 Team。這三個 Team 各有各的擅長技能,但製造出來的成品,相較於最終成品來說,都只是「零件」,都不能(或不打算)單獨拿出去販賣。這樣的分組模式,我們稱為 Component Team。
因為自己製造出來的東西無法單獨販賣,每個 Component Team 的產出雖然重要,但卻無法馬上產生價值,因此,Component Team 彼此之間的「橫向溝通」就變得很重要。
我們來看 Larry 他們的偉大重構案,首先 DBA 進來沒幾天事情就「做完了」,於是就走了。問題來了,如果你要說 DBA 的工作與其他 RD 差很多,無法互相 Cover,那好,我接受,但同樣是只待幾天,為什麼就不能改待最後那幾天呢?
其次前端跟後端在開發流程中如果分開兩個 Team,會發生什麼事?最常見的就是我們倆同一個時間點最看重的事情不同。就拿大重構來說吧,後端想先做會員系統,前端想先做帳務系統,各有各的考量,誰也不想聽對方的是常見的情況,這麼一來,我們各自生產出來的「零件」,在變成真正產品的「等待期」,就會變得異常的長。別忘了這是一個預計 5 個月、實際做了 8 個月的超大專案,不同 team 安排同一件事的時間差,是有可能長達好幾的月的。
你說,我們可以「加強橫向溝通」,協調一下,這三週一起處理會員系統,下兩週再一起處理帳務系統,如何?嗯,也是不錯,但,一個系統的元件那麼多,不太可能每個子系統的每個元件的工作量都一樣大。如此一來,還是很有可能出現「我前端做完了,在等後端」的情況。這種情況一旦發生,前端同事在等待過程中要做什麼?總不能發呆吧?於是前端的 Team Leader 會怎麼做?一般要嘛「去做下週的預定工作」,不然就是「回原 Team 幫忙開發新功能」,對吧?
可是這麼一來,半成品不就又增加了嗎?
在 Component Team 分組的情況下,無論你怎麼努力「橫向溝通」,都永遠阻止不了跨團隊半成品的發生,也阻止不了這些半成品的累積,因為,「沒什麼力量能強過 Team Leader 對自已組的 KPI 達標的渴望。」
那怎麼辦?
我們假設「對自已組的 KPI 達標的渴望」這件事是亙古不變的,那如果這個組的產出物就能包含這個產品呢?什麼意思?意思就是這個團隊自己就具備「為產品增加完整功能」的能力。也就是說,每一個任務放進來,我這個團隊都有能力能解決,於是,我只要想辦法增加我團隊的生產力,產品的成長速度就能提升。同時,我再專心安排好工作的順序,就能確保團隊永遠在做「最重要的工作」。
有人這時會 Argue:「那這還不是一樣?還是會有半成品的問題不是嗎?」
的確,各位試想一個極端情況,就算我是獨自一人開發,也是也有半成品的呀!難道一個功能的三個 function,只寫完一個不算半成品嗎?
我想還是算的,只是 Scale 不同,半成品大小不同,存活時間也不同。一個半成品放到一個跨團隊的大組織上,可能要花三週生產,存活好幾個月(Larry 他們的大重構就是),放到一個 5 ~ 6 人的小團隊中,可能花兩天生產,存活半天到一天不等,放到 Pair Programming + TDD 的流程中,也許只要花 5 分鐘生產,存活兩三分鐘。
半成品的壽命越短,代表它變成產品功能的速度越快,這時若搭配好的後續追蹤與修正方向,每一份投入的成本,其回收價值也就可預期地能提高了。
付出一樣的時間成本,放著無法交付的東西越少,不就代表 ROI 越高嗎?
Feature Team 在敏捷開發的流程中,很常被建議使用,其中一個原因就是其能縮短半成品的壽命的特性,與敏捷開發減少浪費的精神剛好不謀而合。
敏捷開發還有另外一個精神,就是要「價值軀動」。以 Scrum 來說,當 PO 把需求依重要度排序完後,很有機會發生一件事,就是「我的工作做完了,但現在排行第一的工作,用上我的專長的比例很小」。
遇到這種情形,一般照專才專用的思維的話,很容易做出「那我去領後面的工作」的決定。這個做法看似合理,畢竟做專長的事,安心又快速,對吧?可是,我們不就是為了減少浪費才組成 Feature Team 的嗎?現在一遇到不熟悉的工作就跳過,會有兩個問題:
那不就降低價值了嗎?那還怎麼敏捷呢?
「怎麼辦?」
其實答案剛剛已經不小心透露了:也就是 Pair Programming。假設我們回到分工作的第一天,在領工作時我們就注意各技能的搭配,如此一來,遇到而要使用原先不熟悉的技能時,我就可以在另一位較擅長的同事的輔助下,直接從實戰中學習。一般來說,在轉跳語言或技能時,我們不擅長的都是「框架」與「眉角」。這些如果要自學,大多都得多踩幾次坑才能學會,但如果有人帶,那麼學習成本會低得多。
在筆者實際帶團隊的經驗,一開始會覺得卡卡的是很正常的,但時間一長,這些不熟的語言框架,用著用著也就習慣了。就算偶爾真的遇到很深的坑時,這時因為是 Feature Team,該語言最擅長的伙伴都在團隊裡了,在大部份的情況下,隨時 call out 一下請求支援,其實也就解了,而這是我自己遇過的坑,我研究不出來,我 call out 請求支援,我看著神隊有幫忙解,一串操作下來,多看幾次我也就學會了。
當然,我不太可能因此就變成該語言工具的專家,但一般簡單的工作我已經能做了,而我依舊保持原技能的專長地位。如此一來,團隊在領工作時,其彈性就能拉到最大,我們的「最重要的工作一定要最先做」的原則,就沒那麼難遵守了。
「這麼說起來,Feature Team 就一定比較好嗎?」其實也不一定。有些技能跨度很大,需要好幾年的專業培訓,並不是用 Pair 的方式就能習得的,例如 3D 繪圖、遊戲企劃等。如果你讀了 Kuma 的幾篇文章,回去硬幹,叫後端工程師去跟 UI 設計師 Pair,學用 Figma 畫圖…先說好,把人家逼得離職可別回來怨我!
同理,如果你同事間大家都能共體時艱、 相忍為國,只要為了公司好,犧性自己一點 KPI 也無妨;又或者你公司大 PM 就是武功蓋世,完全會知道每個 Team 何時會發生什麼事,並且料事如神,安排的給你的工作永遠是你一做完下一站就會剛剛好需要,那你用 Component 非但會更好,而且效率絕對啵兒棒!
謎之聲:「價值是唯一目的,怎麼分 Team 只是輔助,跟左手一樣。」