2013年12月20日 星期五

閒聊:那些人年,我們一起跳的軟體開發坑

如果您已熟悉 Agile 方法或軟體工程且有開發經驗

那麼這篇菜鳥文可直接跳過啦! ... Orz

我跳「坑」了!


出來創業以來,體會到了一件「大家都知道」的事情:
「學界、業界、創業界之間是有資訊落差的,且越差越大!」
主要是因為真實環境變化大而學界動作太慢 ...

這將會使得學生總是用已逐漸成為歷史的「學習方法」學習可能已經成為歷史的「課程」
最終的影響是:「缺乏與外界接觸的學生,畢業後相對沒有實戰力,甚至完全不能用!」
進到大公司表面上還好,因為有新人訓練的規劃,以讓人變成該公司專用的人才
(顯而易見地,訓練內容是不會教該公司不需要的東西的)
若進到小公司或自行創業,則必然會有一段陣痛期,或者說是「鴻溝」必須跨越 ...

身為在大學研究所點了六年學生技能,後來才從軍人轉職成創業者
我在此分享這兩年來寫 Web, App 以來的心得:

1. 要培養「能」寫程式的能力不至於太難 ...

只要「一直」動頭腦想,有空補上一些學校沒教的書
(請謹慎閱讀/使用/或先不讀 Design Patterns)
寫出來的程式大概都會動 ...
(而且因為寫得很爛所以每次重寫都有進步空間)

2. 要培養「能」架構系統的能力也不致於太難 ...

看多就知道自己該用些什麼
試過就知道好不好用
(但是就算跟專家用一樣的架構,效能跟穩定性並不代表就跟人家一樣)

3. 要「能」順利開發專案很難 ...

真的很難!
客戶的「需求變更」等等外界因素固然會影響專案開發
但是更根本的原因是因為開發團隊:「無軟體開發的基礎知識與實作經驗」

這件事情有點恐怖,因為一次的專案開發,往往要花費好幾個人月甚至人年才能完成
缺乏規劃跟執行的專案,最終導致的成果就是:「一延再延」、「做不出來」、「提前終止」...
因此一個糟糕的專案,可以浪費掉一個人數月至年的人生 ...

有人問為何會無基礎知識與實作經驗?
因為學界內寫的大都是功能性程式,測完數據或是能夠 Demo 就功成身退了 ...
分組作業寫的專案,大都一人(或一神人)就可以直接 KO 掉 ...
至於課程所學的軟體工程 != 真實軟體開發
課程內容除了較廣以外,也往往位於過高抽象化的層級
對於根本沒有實際開發經驗的學生而言,修習軟工的課程是難以感同身受而觸發興趣的 ...
所以說,要一群剛畢業的菜鳥們,要從無到有的開發專案,會遇到很多困難

4. 要「能」順利創業登天難 ...

這不是坑,是大峽谷 -> BJ4。


要把程式寫好、架構出良好的系統是一件很難而必須一直學習的事情

然而,開發稍微大一點點的專案的時候
軟體開發的流程問題就會先被突顯出來,且牽涉其中的人員已經不是個人的事情
一個好的流程能夠讓開發者開心而有效率的製造「垃圾」(只要客戶願意付錢)
但是一個不好的流程,就算是在製造「寶物」,開發者也會覺得很痛苦


「坑」在哪裡?


以下條列一些常見的錯誤:
(這裡以中小型專案為例,不考慮短時間、少許人力可以完成的微專案)

搞不清楚客戶的需求

交付能夠讓客戶滿意的程式,並且依照其功能要求開發出產品是軟體開發的第一要務
所有人也都會同意,要經過與客戶密切溝通、互動,才能夠真正理解客戶的需求
更甚者,初步了解客戶的需求以後,團隊成員們該動起腦袋們,想想如何實作時
一定還會想到一些問題要釐清,或是需要客戶下決定的地方
因此,盡可能定期與客戶溝通,以追逐可能會有所變動的需求會是個好主意

問題來了?要怎麼知道自己已經了解客戶的需求?
不用懷疑!寫下來並且與客戶再次確認吧!
所謂的你「以為」已經了解客戶需求,跟客戶的「以為」你已經了解他的需求
都只是「以為」,且只存在於當下,無法有效傳達給不在該時空的人
用客戶看得懂的 User Story 與客戶驗證需求,才是保險且必要的作法

何以必要?因為舉凡專案開發,客戶一定會詢問開發時間要多久?
倘若沒有記下 User Story,那麼便不可能將其進一步擴展成 Use Case,抑或拆解成細部的任務
更不可能根據任務、以及團隊過往的開發效率「眾人一起」來推估出準確的開發時間
如此一來,要向客戶回答時間就只能「靠感覺」、「靠經驗」了
很容易承諾出一個根本做不完的時間 ...
更危險的是,因為沒有僅抓住客戶需求,產品還有可能不是客戶想要的 ...

這裡另一個常見的情況是,客戶找上門時已帶著所謂「寫好」的文件
文件可能是一張手寫的便條紙、兩三頁 A4 的規格書、UI 的畫面 ... 從殘缺到極度詳盡都有可能
此時要做的事情仍然一樣,協助客戶描繪出 User Story 並驗證需求
有可能只要改幾個錯字即可,或須將畫面轉換成描述更加精確的文字及規則 ...

客戶不會想要開發沒有使用情境的軟體
所以委託給你開發的軟體一定是給 User 在某些情境下使用的
(這裡的 User 未必是人,也有可能是動物或是另一個軟體)
藉由描繪並寫下 User Story 才能夠協助團隊捕捉客戶當前的需求
進而確認潛在的需求、知道「不要的需求」以及確定團隊每個人認知的客戶需求一致

缺乏計畫

當確定要開發客戶的專案,就到了為團隊排定行程以進行開發的時候
以下行程的排法都頗恐怖:
  • 「上線前一週,client 會和 server 串接以進行測試」(也太晚了吧!)
  • 「精密的排定每日行程至半年後」(過度計畫,根本不會準)
  • 「直接讓負責各區塊的工程師動工,他們會知道怎麼做」(確定?)
若以上述最末者為例,若 User Story (Use Case) 及任務等等已備齊
雖可確保當時開發的方向不會偏移掉
但,實作的人員是沒有「優先權」的概念,且預設不會對將來的「需求變更」有所準備的

倘若客戶在開發兩個月後,臨時想看 Demo 了解進度(結果程式架構要到第三個月才能串起來 ...)
或是臨時決定拿掉一部分比較不重要的功能(因為他比較好做,所以就先寫了 ...)
這都很可能會造成悲劇
所以說若只是訂出一個最終的 deadline 而不是分階段驗收
搞到後來產品拖延或失敗的機率是會升高的

因此,規劃階段式的開發週期,並且定期與客戶核對需求會比較保險
從更本質上來看,要排定週期內的行程,及預測自己是否做不做得到一定是比較準確的
這樣的作法額外的好處是,週期若固定,那麼過了一個週期後
透過比較「預測」情況與實際情況,是有助於了解團隊開發效率的
也能進一步改善「預測」能力,以便在下一個週期排定恰當量的工作

階段式的開發->展示->與客戶溝通,除了能跟客戶核對原本的需求以外
也能夠因應客戶的要求排入新功能,並且讓客戶決定優先權
有點像是:「您要增加 C 功能,可以喔!但必須延後 A 或 B 的開發,請您決定?」
在各階段開發的過程中,由於功能一項一項的完成,且可以被展示
所以客戶會安心、而開發人員也可以將壓力分散

埋頭苦幹

執行專案時,最忌諱的就是眾人都同時進入長時間的埋頭苦幹期而忘記專案的初衷與規劃
因此,請記得將專案開發的目標與進度透明化

專案開發的目標,對客戶而言自然就是滿足那些 User Story
對開發團隊而言,就是完成那些 User Story 所拆解出的細項任務
且這些細項任務是該被「估計」要多久才能完成的(不然怎知道此階段團隊能完成多少任務)

當這些必要的前置作業都完成後
開發團隊在短期埋頭苦幹以取得最佳工作效率時
才能夠隨時在休息抬頭時,看見工作目標
並透過比較實際花費的時間與估計值,了解工作效率
除了尋求改善,也能以此為經驗重新預估接下來的任務所需要花費的時間

糟糕的執行力與缺乏測試

糟糕的執行力有分許多層次,在此列舉部分:
  • 寫不出來
  • 寫很久才出來
  • 寫出來,但是錯誤百出
造成上述狀況的原因不外乎是「缺乏程式能力」與「缺乏測試」

工程師要有基本的程式能力才能完成需求的功能
要有一定水準的程式能力才能在時間內完成需求的功能
要有一定水準的程式能力與測試概念,才能在時間內完成需求的功能,且正常運作

補足程式能力,是所有程式設計師都知道要做的事情
資料結構、演算法、物件導向 ... 熟悉與否都會影響到開發出來的軟體品質
然而,「測試」的重要性是容易被忽略的
甚至,我個人認為對於使用 OO 語言的新手工程師而言
若有時間進修,學測試的實用性還遠大於 Design Patterns

理由很簡單:「程式碼總得被執行」

就算不套用書上特定情境的 Best Practices 來解問題
你也能用當前已掌握的知識來解決問題(雖然未必是漂亮的解法)
但是無論如何:
  • 每當寫完一個小 function,總得知道輸出的結果符合不符合預期
  • 每當寫完一個小功能,總得知道運作起來正不正確
  • 每當寫完許多小功能,總得知道相互運作使用時正不正確
  • 每當新增/修改部分程式碼時,總得知道會不會影響到既有的功能
  • 每當完成了一個版本以後,總得驗證在客戶的需求情境之下,系統運作是否正常
在「程式碼總得被執行」才能驗證對錯的情況下
研讀各種技巧、思維來最佳化「測試」這一件事情,是能夠對軟體品質大幅提升的

過度設計

「過度設計」在軟體開發的過程中無處不在,並不是只有在設計初期才會出現
巨觀而言,設計的軟體可能會擁有客戶不需要的功能、或是建構出不合理規模大小的系統 ...
微觀而言,撰寫了很多用不到的 function、為了大量地預留延展性而讓人不易理解抽象架構 ...

可想而知,「過度設計」會帶來的缺點就是「費時」
設計本身要花時間,因為設計而「Block」到其他人進度也會耽擱他人的時間
實作設計會花時間,因為設計太複雜,而得費更多力氣來實作,就得花費更多時間
最後軟體因為複雜度的提高,導致更多的臭蟲,得花額外的時間解決

要克服過度設計非常困難
總結來講,擁有「足夠的開發經驗」就能較妥善的面對「過度設計」的議題
然而,在累積足夠的經驗之前該如何對設計做取捨?

巨觀而言,時時刻刻謹記客戶的需求
微觀而言,隨時記得「程式碼總得跑」這件事情,讓程式碼的目的符合該粒度下的使用情境
甚至,透過優先考量「怎麼跑、怎麼用」這件事,先行實作測試並且同時設計出必要的系統



最後回到創業坑


之所以會有本文,是因為前一陣子看到了一篇文章:
對 Spotify 的組織感到震撼、佩服之餘,我也不禁脫口而出:

「這要怎麼打啊?」
「他們可是組織成了一支軍隊來跟別人打群架 ...」
「我們連願意一起打群架的人都還不多 ...」

我只能說 ... 創業要考慮的面向非常多
然而無論如何,資訊人最終還是得進行「軟體開發」才能做出產品
培養其能力與正向生態系的重要性自不可言喻!


備註:
本文非常簡略而不全面地探討軟體開發時常見的坑
(基本上,我都跳進去過了 ...有的還跳不出來 ox@#.) 
我也盡可能避開專業名詞,盡量換句話說,以練一下表達能力 (結果還不太行)
事實上,本文也是我讀完新手村內的「深入淺出軟體開發」後的心得 (有猜到嗎)
推薦給資訊相關科系大二以上的學弟妹讀讀(附上網友整理的筆記
或許你會因為沒有實際開發過軟體的經驗,因此不能完全理解書中講解的內容
但是留點印象是好的,若能激發你的興趣去了解軟體開發相關的技術就太好了!

沒有留言:

張貼留言