實戰敏捷開發 Practices of an Agile Developer (2) 需求篇

這一章是 Delivering What Users Want。我們總是幻想客戶一開始就確切告訴我們需要什麼,然後做完收工拿錢即可。不過事實總是中途加入一開始沒有提到的功能跟規格變更。敏捷開發不去試圖”擊敗”這些變更,而是把重點放在如何快速辨認及適應這些改變,並在時程及預算內做出真正符合用戶需求的軟體。

Let Customers make decisions (讓金主做決策)

當碰到設計上的決策時,尤其是 business-critical 決策,例如有兩個解決方案,一個複雜耗時長,另一個較簡單花較少時間。這時不要自己先決定,而是準備好資料(優缺點跟耗時估算)向金主(客戶)並用他們聽的懂的語言,讓他們決定。我自己的經驗是常常你打算做的沒有客戶想要的這麼複雜唷,這時候就可以省下這些時間去做真正客戶要的。

記得紀錄下來每個決定跟理由,當然你的問題也不能太技術細節,而是要有關係到 business。當然客戶也有可能說不知道,那麼你只好說出你覺得最好的建議。

Let Design Guide. Not Dictate (讓設計引導,而非鉅細靡遺)

設計文件不要細節到告訴你怎麼實做,而是一張地圖告訴你方向。
傳統作法特別強調設計階段,希望設計文件盡可能詳盡,但是 agile 則建議你盡早進入開發(development)階段,這不代表忽略 design 的意思,基本的 key diagrams 仍是一開始就必須先思考。

agile 建議盡早開始的理由是,再多的設計也只是基於你對當前的需求了解,一旦開始 coding,一切都會變化,不需要把時間浪費在詳盡的設計。

“There’s no sense being exact about something if you don’t even know what you’re talking about.” -John von Neumann” 馮曼紐大師如是說

當 designer 要求 coder 必須按照設計實做,但是系統現實和已經存在的程式告訴 coder 這並不會是最好的設計,真是糟糕,設計的時間已經花了,沒有時間重來。於是 coder 在有壓力的情況下只好實做出他明知不對的程式。這種嚴格要求 requirements-design-code-test 流程的瀑布式開發已經落伍了。

而 Agile 要說得是,只有在要被實做的時候才有需要詳細的設計。我們可以將設計分成兩個層次,策略性的(strategic)和戰術性的(tactical),前者不需要詳細到 mehods 參數,物件之間的互動次序,這些都是戰術層次。前者可以討論到可能的 class design 以及他們的責任,及 CRC card design 也很適合,一個 Class 被描述成 Class name, Responsibilities, Collaborators 等,一個適合的設計即使需求稍有變化也可以輕易實做出來。

一個好個策略性設定應該扮演地圖角色,告訴你目標方向和限制,任何設計都只是一個起點,一旦開始開發你就必須一直演進下去。

agile 的精神不是告訴你設計、計畫不重要,缺少任何設計就進入 coding 是非常危險的,就像美國總統艾森豪所說得 ” The plan is worthless. The planning is essential.”,設計的過程才是收穫最多的地方。(XP流程有本書叫 Planning Extreme Programming, by Kent Beck&Martin Fowler 也是這個原因,書名叫 Planning 而不是 Plan)

Justify Technology Use (評估使用的技術)

根據需求來選擇使用什麼技術、語言或 framework,每項技術都有優點缺點跟 trade-offs。
“The less code you write, the less you have to maintain”。可以下載到的東西,不需要自己寫。

Keep It Releasable (保持可以 Release 的狀態)

每次 checked-in 的 code,都要是可以讓系統可以執行的 code,避免 unreleasable 的狀態。
當你跟一個團隊一起工作,你必須了解到你的 changes 是會影響整個 team 的生產力,一個 unreleasable 的狀態讓整個 team 卡在那裡。你不能忍受別人 check-in 的 code 把程式搞爛到不能動,別人也不喜歡。在 check-in 之前,請確認以下兩個步驟:

1.在 check-in 前跑一遍所有的 unit tests
2.check out 最新的程式碼,時常發生別人剛 check-in 一段與你不相容的程式碼。

當然,最好的辦法就是建置一個 continuous integration system (CI),當有一個 check-in 時會自動 check-out 出來執行測試並產生通知。

說比做容易,將 database scheme 跟 external files 也送進版本控制系統,讓相關更動都可以被測試。大的更動可以透過 version control branch 分支來處理這個問題。

如此一來,一個隨時可以動的軟體,金主、客戶、QA都隨時可以看到最新會動的版本。

Integrate Early, Integrate Often (盡早整合、時常整合)

許多人會會延後整合,畢竟系統最後再整合就好,只要現在自己的 sub-system 可以動就好。但如果你一直只開發自己的東西,而越慢跟別人的東西整合在一起,越是辛苦。建議整合的次數從一天好幾次,到至多兩三天也至少有一次。

我自己的經驗是,你在分支(branch)開發一個功能,而主幹(trunk)同時也有別人在繼續進行,這時候建議時常要從 trunk merge 進你的 branch,可以的話每天進行,而不是等到最後才進行合併,最後才合併可能就merge不起來了,差異太大。

隔離開發(isolate)可以讓你開發更快避免干擾,但 isolate 與 integrate 不是不能同時進行,我們可以透過 mock object 技術在 isolate 的環境中測試你的 sub-system。透過盡早整合,你會發現你的 sub-system 與其他 sub-system 如何互動,越早了解問題所在,修好它的工作困難度就越低。

Automate Deployment Early (及早自動化佈署)

自動化安裝步驟(Install or deploying your product should be easy, reliable and repeatable)。為什麼需要呢? 反正又不常裝,手動就好啦?
安裝步驟不只有你而已,還有 production 跟所有 programmers 跟 tester。如果最後 deploy 才做,常會發生東少西少裝東西的情況,常常機器環境改了程式就壞了。趁早做好安裝程式也可以讓 QA team 及早測試不同機器環境跟設定的 deployment。安裝步驟中也可以 check 必要的 dependency,趁早排除環境因素。
有了自動化佈署,在 web 專案中,可以快速上線的能力將會非常方便,特別是有bug馬上修好的時候。
另外一提的是記得提供 user 完全移除的辦法。而 Day One 就有安裝程式的另一個好處是,馬上就可以給客戶可以安裝的 demo 版。

Get Frequent Feedback Using Demos (透過經常的Demo得到回應)

我們總是時常聽到”凍結需求”的要求,但現實是需求如流水。如果真定住,往往也是錯的。沒有人的心思是固定的,特別是你的客戶,這是人性啊。當提出需求後,總是還會繼續想怎樣實做會更好。如果你只是依照一開始的需求去做,那最終是不會讓客戶滿意的,因為你只是生產出他們開口要的,而不是他們想要的。

解決之道是降低 iteration interval 開發週期時間,我們在一個 iteration 做好分析/設計/實做/測試,然後得到 feedback。過長的週期容易走偏,持續性的短週期與客戶溝通,對每個人都是有利:客戶可以知道進度,而且可以儘快把想要的修改跟 feedback 表達出來,而程式設計師也可以因此讓程式更接近客戶想要的,客戶也可以依據開發的情況和還有多少時間預算,來表達開發的優先順序,

儘快得到 feedback 吧,如果你的週期是一季以上,請改用一週到四周 (單雙週較理想) 向客戶 demo 並得到 feedback。這些 feedback 包括錯誤修正、建議、需求更改,功能加強等等都需要利用 ticket tracking system 加以管理。

在表達需求的時候,建立一份 Project Glossary 術語列表是很重要的,讓程式設計師跟客戶對名詞詞彙取得定義,可以大大避免誤解。

Use Short Iterations, Release in Increments (短開發週期,釋出新版本)

有了一到四周的開發週期,接下來我們還希望上線的 release 是以 1~6個月為週期,釋出即使功能少,但是穩定可以運作,可以提供客戶操作價值的版本。一個計畫超過數年的軟體還無法 release 出一個版本讓客戶使用,註定失敗。

找到產品最重要的核心功能,儘快上線讓真正的使用者去使用。沒有人願意去等超過一年的軟體。即使是 NASA 複雜太空梭計畫也可以使用這種 incremental 式的開發,再大的產品也可以拆出有用的一整塊實做出來。

快點上線的好處是可以儘快獲得收益,讓專案更有力量繼續進行,得到 user feedback 什麼是用戶真正最想要的功能,什麼是你本來想要但是其實客戶不需要的功能。開發人員也希望快點得到成果,一個計畫一年後才釋出的軟體讓人提不起勁,能得到真正用戶的正向鼓勵絕對有助於生產力。

而 iteration 開發週期不是一定要緊接著的,我們也可以在以四周為單位的 iteration 中安排一週的 maintenance week 然後再進到下一個 iteration。

Fixed Prices Are Broken Promises (小心定死的價格)

每個客戶來總是期望問多久完成? 多少錢? 但是一個大的固定預算,固定時程的軟體專案卻是非常危險的,尤其是差異性高的軟體產品,我們較難根據上次的開發經驗判斷這次的需求會花多少功夫。傳統上為了能夠做較大的案子,就會去做很多的 COCOMO 或 Function Point 分析,但是這些都不是 agile 所希望的方式。

Agile 會建議你盡量將第一次的約簽小,在6~8周內完成一個可以上線的產品。有了第一次的經驗,我們就有更好的實戰估計能力。對客戶來說也是保障他可以在短時間內看到成果,也讓客戶可以根據預算控制他們要的功能。當然,如果一點空間也沒有,那麼只好加強估計的能力了。

參與討論

4 則留言

  1. 看完你的心得和重點以後,感覺敏捷開發似乎就是專為了網站開發所設計的方法,應用在安裝式的軟體似乎不太適用(安裝式的軟體可不能越快”上線”越好),是嗎?

  2. 不是的,Agile 並沒有這樣的差異。我寫”上線”是因為我自己照習慣說。

    就算所謂的安裝式軟體不也是盡早釋出可以用的版本得到 feedback 越好嗎? 像 Mac 上面就有非常多 ISV 開發的軟體也是從 1.0 beta 開始出起,搭配自動升級的功能 (現在電腦幾乎都是上網狀態),只要軟體一出新版也可以很快地推送讓用戶升級。

  3. 雖然我沒有實際太多的接案,但因為會寫程式在許多的場合下都”友情”的幫朋友寫,我認為敏捷開發的理念很符合這些狀況,不僅是WEB-app,而是很多. :)

發佈留言

發表迴響