l

2010年4月18日 星期日

你的軟體架構有多軟

04/17 22:49 ~ 04/18 00:42

『軟體』這個名詞有時候真是害苦了從事這個行業的人。『軟體』---->『軟的物體』,顧名思義就是一種像是『黏土』一樣可以捏來捏去,沒有固定形體的東西。原本客戶一開始要的是小花貓,你作到一半他忽然要改成頭上有個『王』字的大老虎,你也要想辦法生給他。

客戶:這個很簡單的啦,不是改幾行程式就好了。
你: 靠... 左邊走...

根據 Teddy 的經驗,大部分的軟體系統其實都很『硬』,隨便改了一行程式都可能會額外『製造』出意想不到的 bugs。雖然實務上軟體是很硬的,但是你的客戶或是老闆卻不斷的催眠你:『軟體是軟的,軟體是軟的』。久而久之,涉世未深的 programmers 居然也開始萌生『軟體應該是軟的喔』這樣的想法。為了讓自己手邊硬到不行的軟體變軟,programmers 們便開始嚐試各種作法,其中一個常見的作法是:設計一個 包山包海 具有可擴充性的軟體架構。

鄉民們如果查一下軟體架構的內含,應該知道軟體架構主要是用來滿足availability, modifiability, performance, security, testability, usability 以及其他族繁不及備載的 nonfunctional requirements (或稱為 quality attributes)。傳統上(應該說主流的想法,因為到現在大部分的人也都還這麼想)大家都認為要在系統開工之後才來考慮 nonfunctional requirements 通常會造成系統大改,成本太高。這有點像是,當你蓋好了『一品苑』之後才發現它長得太高了,可能會讓有心人士可以直接把總統官邸當成靶場,違反了『security』這個 nonfunctional requirements。房子都蓋好了不然是要怎樣?(套句遙遙的廣告台詞:這是你的 security,不是我的security ...XD)不管是要總統搬家(誰想出這個乞丐趕廟公的餿主意?)或是停發使用執照,成本都很高。

所以,雖然 agile methods 告訴我們不要做 big up-front design,但是軟體架構身份這麼特殊,是否應該享有特權,等軟體架構設計好了再開工?

***

問題來了,怎麼才算是『軟體架構設計好了』?仔細想一想,這是一個『先有雞,還是先有蛋』的問題。如果鄉民們相信 agile methods 所倡導的 iterative and incremental development,那麼應該知道:

  • 三心二意的客戶以及劇烈變化的市場隨時都可能改變需求。
  • 客戶的需求通常在他看到或用到軟體之後會越來越明確。
  • 因此,軟體專案不必也沒辦法等所有需求都確定才可以開始(因為需求永遠都在變啊,要等所有需求都確定才開始那不就等於永遠都不會開始)。

在需求會變動的情況下,怎麼設計一個軟體架構來滿足可能會變動的需求?另外,如果軟體架構可以或應該在軟體開發之前就完全決定,那是否表示需求就要固定?

以上兩句繞口令可直接忽略,重點是,如果依據傳統的作法,在 coding 之前就要把軟體架構設計好,會引誘開發團隊進入 big up-front design 的陷阱。更慘的是,就好像在 waterfall 流程中通常會要求客戶對需求畫押保證不再變動一樣,結果就是.... 不管你事前花了多少時間,設計好的需求與軟體架構,在 coding 之後幾乎不可能不改變(請不要拿美國 NASA 或是國防部的案例來嗆聲... 台灣大部分的開發人員在有生之年應該都沒有這個榮幸做到這種案子)。

講了這麼多,那到底要怎麼做?首先就是心態要調整一下,要先相信軟體架構是有可能採用『逐步成長』的模式來慢慢成型。這一點當然是『說得比做的容易』,因為『選對軟體架構可以讓開發團隊上天堂,選錯軟體架構就只能住套房』。看到其他人用好的軟體架構或是 framework 過的自由自在的日子,而自己卻在住在套房中被綁手綁腳的,這種感覺會讓開發團隊覺的自己很遜,最後可能變成『砍掉重練』(傳說中的設計魔人是否就是這樣誕生滴?)。

由於這個問題太難了,因此 Teddy 就不要不懂裝懂,留待各位鄉民們自行發揮。不過以下有一點資料可以參考一下。最近從 Teddy 在讀 Implementing Lean Software Development: From Concept to Cash  這本書,裡面提到:

The objective of a good software architecture is to keep such irreversible decisions (nonfunctional requirements such as security, performance, extensibility, etc) to a minimum and provide a framework that supports iterative development.

It is time to abandon the myth that architecture is something that must be complete before any development takes place.

要如何 “keep irreversible decisions to a minimum and provide a framework that supports iterative development” 說真的就要靠硬功夫了,以下是幾招常見的標準招式:

  • Plug-in Architecture
  • Layered Architecture
  • Model-View-Controller
  • Service-Oriented Architecture
  • Component-Based Development

前面三招是目前 Teddy 的最愛...


友藏內心獨白:歡迎喜歡吃『軟飯』的人加入軟體開發行列,讓軟體變得更軟 !@#$!#%&

5 則留言:

  1. 之前有一次試著在需求/設計/開發階段做Iterator, 結果案子發散到不可收拾, 不知道您是怎麼做收斂的?

    回覆刪除
  2. Hi Hector:

    在開始一個新的專案之前,Teddy 會先『偷跑』把軟體架構框架先定義好並且做出一個雛型出來(姑且把這個偷跑階段看作 iteration 0,耗時幾天到2周左右)。此時的軟體架構只是很粗略的概念驗證,用來評估此架構能否支持後續的功能開發 (算是一個空殼子)。專案正式開始之後藉由每個 iteration 完成若干個 stories (需求) 來逐步的完成軟體架構中的每個元素。

    當然這麼做是有一些先決條件。如果開發團隊中沒有對於軟體架構比較有經驗的人,或是開發團隊對於新的專案領域之前沒有類似的經驗,那麼要在短時間找到一個軟體架構雛型是比較困難的。例如,Teddy 沒有做過 ERP 系統,也不知道有沒有現成的 ERP 軟體架構可以直接拿來抄(直接抄襲合適的軟體架構這是很有效也很管用的一招),在這種情況下如果要 Teddy 在兩個禮拜內定義出 ERP 軟體架構雛型可能就沒辦法達成要求。此時,也許可以考慮混用 UP (Unified Process) 和 agile methods。套用 UP 的術語,在elaboration phase (大概 2-6 個 iterations 左右,依據專案大小而調整) 之後 architecture baseline 需要成型,這樣可以避免過多的 up-front design 以及降低『發散到不可收拾』的問題。

    當然,agile 死忠者可能會說,不要想那麼多,直接做功能,在透過 refactoring (refactor to patterns) 慢慢建構起軟體架構。不過說真的除非開發團隊的人都很強,不然這一招很有可能會演變成您所說的『發散到不可收拾』。

    最後,可能也是最重要的一點,就是平常要多看 software architecture 與 design patterns 的書或資料。如果全部或大部分的開發人員都經驗不足,何方法或是流程能幫上的忙就很有限。

    回覆刪除
  3. 這邊講的『偷跑』比較像是 iteration 0,就是專案開始之前的準備活動。就 Teddy 的認知 spike solution 比較像是專案已經正式開始之後,用來將某件不確定性很高的工作區分成 spike activity 和 implementation activity(錯了請更正 Teddy)。不過,不管如何,其實精神都是一樣的,所以你說得沒錯,就是 spike solution...

    回覆刪除
  4. 多使用UML 做分析就好了

    回覆刪除