jim yeh on 十一月 12th, 2007

本文係投稿於 CNet / ZDNet Taiwan 的初稿,並分為兩篇文章刊出,未經 ZDNet Taiwan 編輯,其內容可能會略有差異。

如眾所週知的,軟體開發專案具有高度不確定的特質。因此,為了降低需求變動的風險,在專案初期,軟體開發者往往會花費許多的心思,設計出具有彈性的軟體架構以適應未來可能的需求變化。大部分的開發者都了解軟體需求是不可能不改變的,但他們希望不管軟體需求如何變化,軟體開發的設計概念都不會因此受到影響或改變,如果可以做到這一點,軟體開發就會變得比較有效率,同時也能確保所開發之軟體的品質。

然而,現實總是和理想存在著一些落差的,專案的演變往往會超乎開發者事先的預期。尤其是當專案的驗收日期愈來愈接近時,專案可運用的資源也會愈來愈少,專案或許已不如剛開始時充滿了未知與不確定性,但相對地,專案的可變動性也愈來愈小。因此,在專案後期出現專案問題,或是需求的變動,相較於相同專案問題或需求變動在專案初期出現而言,會顯露出更為嚴重的危機與壓力的。

每個人都希望寧願事前多做一些風險管理,勝過事後的危機處理,而且後者的壓力是很容易讓做錯事的。然而,軟體易變的特質及專案環境的不確定性讓人難以捉摸,更不用說預測變化了,卻只能在事後才徒然留下「千金難買早知道,萬金難買後悔藥」的感嘆。但問題還是要解決的,到底軟體開發者在遇到這種危機時該如何處理呢?

軟體品質的問題

我們是否能拒絕變動?或許凍結需求,拒絕變動可以讓軟體開發成功,但這樣的做法卻不會讓專案成功。因為軟體專案如果無法符合軟體需求者的需求,專案並不能算成功,以軟體需求者的立場而言,客戶永遠是對的,他們並不在意技術有何難處,但卻會很關心軟體能否幫他們解決問題。所以,如果開發者所開發出來的軟體不能符合他們的需要、為他們創造出價值,軟體需求者會認為軟體品質並未達到目標,未符合品質目標,專案當然不能算是成功的。

如果變動無法拒絕,那麼只好接受它了,但這對軟體開發者而言,往往是重大挑戰。根據筆者參與軟體專案開發的實務經驗顯示,因為需求變更的原因,要向客戶去爭取專案合理的時程及增加開發成本其實並不容易。所以在專案時程與成本無法變動的情況下,想要解決專案的問題與滿足使用者的需求,很容易因此影響到產出軟體的品質。

其實從專案管理的三重限制(triple constrainst)的觀念應不難瞭解到軟體品質與專案時程、成本及軟體需求之間常會相互影響,因此,當專案時程及成本無法變動時,我們很容易可以理解軟體需求的變動將會影響到軟體品質。

而在實務上,軟體開發專案常會時程壓力、專案得到的支援與資源不足等原因,使開發者沒有足夠的動機、時間、與精力來分析問題以設計合理的解決方案,取而代之則是直接修改程式,以符合軟體需求者所提出的功能,就算發現了因此將會破壞了設計上的結構也在所不惜。就短期而言,在設計的結構上做一些犧牲,雖然如此可以換取增加軟體需求者所提出功能的空間。但長期下來,缺少對問題分析與完整設計的系統,自然而然會衍生出許多軟體品質的問題。

解決問題的洞見觀瞻

如此看來,軟體專案的需求變更,常會造成開發者的左右為難。計劃趕不上變化,現實就是變化無常的,所以藉由預測與控制要變動不會發生是不切實際的。但擁抱改變似乎沒有想像中的那麼單純,隨著需求的變化無常,程式碼也愈來愈複雜,造成更高的軟體出錯的機率,增添程式碼維護的困難度。

情況真的無法改變嗎?那也不見得,筆者認為想要脫離這種兩難的困境,開發者應先具有洞見觀瞻,認清軟體開發者應該面對現實,但應該避免因為捨本逐末的行為模式而形成自廢武功的後果。

如圖所示,表面上,忽略設計的行為雖然可以省下時間來修改程式,以解決眼前的專案壓力,但因為環境仍舊不斷地在變化,所以開發者忽略設計的狀況會一直持續地發生,才能節省更多的時間來對變化做出回應。然而,長久的忽略設計,卻會影響軟體設計的概念完整性,結果將會產生軟體設計結構不良的後遺症,專案壓力最後當然會不減反增了。

lost-design.PNG
當開發者長期地忽略設計,他就不會花心思在軟體的概念性設計上,更不用說提昇軟體設計的抽象化思維的能力了。換句話說,開發者只能憑藉軟體實作的技巧來解決問題,但這是很危險的,因為這樣程式碼只會愈改愈複雜,變得難以令人理解,同時溝通起來也會變得格外困難,出錯機會也就增加了,造成更多的專案壓力。

另一方面,長期忽略設計,設計的概念不夠完整,也就是設計會遺漏一些重要資料,因此設計無法重覆地被運用,而實作上又充斥了許多的特例,存在許多的資料細節,因此要重覆使用也會有困難。也就是說,軟體的設計缺乏完整及一致性,其實作又與業務邏輯之間產生複雜的相依性,因而軟體各元件其實缺乏再用性與彈性。用軟體開發領域中常聽到的話來說,就是開發者要不斷地重覆「造輪子」,軟體沒有足夠的彈性以適應需求的變化,專案壓力當然會一直居高不下。

由上述分析不難發現,提昇設計上的概念完整性對於軟體開發者而言,是非常重要的能力,因此,軟體開發者在設計上選擇讓步,無異於自廢武功,這樣將犧牲了設計概念的完整性,最後終究是無法解決問題或滿足客戶期待呀。

要如何不自廢武功?

自廢武功無疑是下下策,但軟體開發者在面臨專案的巨大壓力下,要如何不自廢武功呢?顯然忽略設計的做法是不可取的,因此,單單只利用系統實作技能來彌補設計不完整的缺憾往往常會把問題弄得更複雜,這樣做其實是本末倒置的。筆者認為開發者應該重視設計概念的整體性,這樣才能用更簡單而富有彈性的設計來解決問題,而要達到這個目的,開發者必須更專注在問題分析與概念設計的能力。

因此,當軟體需求者提出了他們希望軟體應該要有的功能時,開發者還必須深入地思考為什麼他們會希望軟體應該要有這些功能,並深入地探討他們所面對的真正問題是什麼。因為軟體需求提供者只是站在客戶或使用者的觀點來看待軟體,技術並非他們的專業,所以他們對系統功能的理解很有可能並沒有辦法解決問題,因此開發者應該先找到需求者的問題而非功能。因為只有在了解需求者的真正問題後,開發者才能站在問題的角度來思考解決方案,也才能發展出適合的設計概念來解決問題。

筆者舉兩個實際的例子來說明概念設計對解決問題的重要性。有一個在開發中的系統,客戶發現在接收某種訊息時,其資料拆解出現了問題,我們探求其原因,發現在某些特殊 tag 之後,要跟隨在後面的 tag 資料都當成那個特殊 tag 的內容,而此系統的訊息資料拆解設計沒有支持這樣的概念,所以會造成這個 tag 的資料無法正確處理。

但因為此類訊息是屬於標準格式,而訊息規格卻沒有交待有這種特殊的 tag 規則存在,到底這是業界的不成文規定還是某些交易伙伴特有的做法呢?是不是還有其他的特殊 tag 呢?於是我們向客戶表示,必須要請他們提出更完整的資料,否則我們是無法處理這個問題的。

我們的回應,促使客戶更深入地去探討這個問題,據他們表示,以前的系統並沒有處理到這個問題,因此,得確還有一些特殊的 tag 沒被注意到,問題似乎並不如一開始所想像的那麼簡單。

然而,如果我們只針對客戶提出的問題來修改程式時,程式碼將會變得更複雜,因為在設計不改變的狀況下,所有接收 tag 處理的實作都會大受影響。但如果從設計概念上加入註記隨後出現 tag 都包括在某個 tag 內容的概念,就不會大幅影響原來程式的實作。只要在接收那個特殊 tag 處理的實作中設定註記,問題就可以迎刃而解,甚至可以變得更有彈性,例如可以設定某個 tag 有還原註記狀態的功能。

還有一個例子是,在一次專案會議中,某位系統分析者提出一個系統問題,她指出系統在案件的處理過程中,多人重複派送同一個案件會發生問題,她懷疑是因為多執行緒的案件分派機制所造成的,並認為如果讓案件分派不是多執行緒,問題就應該可以解決

不少開發者也認為讓分派機制不要那麼複雜就可以解決問題了,但他們也了解到,不用多執行緒,案件分派的速度會變慢,客戶很難接受這種做法,所以他們會很希望有人能和客戶協調溝通。

但筆者卻認為多執行緒的案件分派卻並不是問題的成因,雖然,在案件分派機制是多執行緒的情況下才會發生這個問題,但我認為問題較精確的說法應該是問題一直都存在,只是「多執行緒的案件分派」讓它浮現出來罷了。

筆者對提出問題的系統分析者質疑為什麼會有「多人重複派送同一個案件」的情況發生,她提到那是因為客戶的要求,因為客戶希望針對同一個案件,不同單位的人都可以處理同一個案件。原來是因為一開始系統分析者把案件的處理資訊與案件放在一起,但一旦當許多人可能會同時處理此案件時就會發生問題了,因為每個處理都是同一個案件,系統將不知如何分辨它們的不同。

這是一個典型的例子,缺乏整體概念設計的模型常常會讓問題弄得很複雜,系統分析者純粹以技術實作的眼光看問題,而非以問題領域的角度來建模,她把處理案件的案件與原始案件混在一起了,但以業務邏輯的概念來看,對某案件的處理本身是另一個案件,其有獨立的案件編號,所以只要用業務的眼光來修正設計模型就可以解決問題了,而不是取消案件分派的多執行緒功能。

從這兩個例子可以發現,分析出問題背後的問題,然後才能在概念上發展出有效的設計藍圖,才能用簡單而富有彈性的方式來處理問題,同時,這樣做也讓人可以容易理解與相互溝通,因為大家是針對問題領域來了解及溝通而不限於特殊技術。

問題分析並不需要花費太多的時間,因為只要找出問題的關鍵後,剩下的就簡單多了。當然,這需要不斷地練習,才能培養出敏銳地觀察力以及獨立思考的能力,而對於比較複雜的問題,也可以藉由集思廣義的方式來促進集體反思。良好的問題分析與概念化的設計能力才是軟體開發者能否適應環境變化的重要能力。總而言之,軟體開發者如果不去加強分析與設計的能力,專案壓力將會壓得他喘不過氣來,自廢武功往往是必然的結果,這只會耗弱軟體開發者的應變能力呀。但筆者相信只要我們多觀察、多思考、多學習,其實是可以打破這種宿命呀。



     

7 Responses to “軟體開發者不應該自廢武功!!”

  1. monsta 說道:

    同意,需求變更不是簡單的無法拒絕就接受或無法接受就想辦法拒絕這麼簡單,供需雙方願意去溝通並找出問題背後真正的solution是很重要的,愈是想快刀斬亂麻的解決,就表示處事者愈沒有進入Groan Zone的膽識而已~

    但願意進入Groan Zone的人,都了解慢慢來比較快的道理,偏偏這種人是少之又少~

  2. [...] 所以,勇敢地去落實理念,我們就會獲得更多,停留在原地只會失去成長的機會,同時態度也會愈變愈消極。當然,追尋之路看起來人總是不多,就像在〈軟體開發者不應該自廢武功〉的迴響中,monsta 提到了: 愈是想快刀斬亂麻的解決,就表示處事者愈沒有進入 Groan Zone 的膽識而已~但願意進入 Groan Zone 的人,都了解慢慢來比較快的道理,偏偏這種人是少之又少~ [...]

  3. [...] 問題並不在於軟體功能無法說加就加,說改就改,而是在收尾巴的過程中自廢武功。不根據需求的變動或軟體的現存問題規劃出合適的架構與概念設計,現存設計怎麼會有足夠的空間來容納新功能?就好像想在堆滿東西的房間中,還要硬塞一些東西進去,這樣的結果當然很容易會讓我們在這房間中跌倒。 [...]

  4. 阿倫 說道:

    感謝你ㄉ分享資料!

  5. [...] 顯然這將會讓專案團隊陷入了以短支長的窘境,而且對軟體缺陷,沒有「早期發現,早期治療」的結果,是必須付出龐大的代價。例如工程師在眼前問題緊迫的情況下,選擇自廢武功,因而降低軟體的結構性使得 bug 愈改愈多,更不用說工程師的士氣與能力的低落了。等到工程師負擔不起龐大的 bug 負債時,信心崩潰就出現了,這時乙方的 feature request 就不會再被甲方所信任而接受了,就如如同人在〈專案不確定感的焦慮與迷思〉所舉的真實案例。 [...]

  6. [...] 如果該欄位是必要欄位,那訊息中此欄位出現空白就應該認定資料錯誤;但如果它並不是必要欄位,那麼就應該定義訊息此欄位為非必要欄位。而在前者的狀況下,我們應該增加一條業務邏輯來檢核必要欄位不可為空白,否則將拋出異常的回應。如此就非常簡單解決問題,而不該採取自廢武功的作為,因此那只會顯露出開發者缺乏抽象化思考的 common sense 呀。 [...]

  7. [...] 同人主張的解決方案並不是疊床架屋,相反地,長官堅持改變資料表結構來因應少部分的特殊需求,卻是在架構上自廢武功的行為。為什麼長官寧願自廢武功也不願意面對現實採用靈活彈性的設計策略呢?這固然是期待設計必須滿足情感上的需要,而使他沒有面對現實。但為什麼他不能意識到自己應該面對現實,而認為變更架構不會對專案帶來什麼大問題?同人發現他原來是個超理智型的管理者,人在他的世界中根本就不存在,因此也就不會有人的問題。 [...]

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">