Domain-Specific Development 與 Domain-Specific Modeling

4/30/2008
上回寫了一點關於 Domain-Specific Languages(DSL)的粗淺概念,之後我又看了一些跟 domain-specific 有關的資料,主要是《Domain-Specific Development with Visual Studio DSL Tools》和《Domain-Specific Modeling》,所以這裡就個人的理解做點筆記,簡單介紹一下特定領域開發( Domain-Specific Development;DSD)和特定領域塑模( Domain-Specific Modeling;DSM)的概念。當然,目前還是停留在 scratching surface 的程度,離實作開發還很遠啦。

標準化與客製化

DSD 和 DSM 都是強調特定領域(domain-specific)的軟體設計方法,而且都是以 DSL 為其基本要素。所謂的特定領域開發或特定領域塑模,指的是針對特定問題領域--尤其是比較小的問題領域--來進行軟體系統的設計。進一步說,開發人員必須為特定領域定義一套語言(DSL),並使用該語言來塑模軟體,而且這裡的「塑模」還有另一層重要的涵義:產生程式碼。

可是,為什麼要強調特定領域?當我們在開發複雜的軟體系統時,不就已經是針對特定的問題領域來進行設計嗎?

是這樣沒錯,但我們往往只能 reuse 程式碼,而未能直接 reuse 設計時所建立的模型。也就是說,碰到一個類似之前開發過的系統時,大部分還是重新設計。雖然經驗再加上複製剪貼的工夫已經能夠加快開發速度,程式碼也逐漸累積可重複使用的框架和基礎元件,但這樣的 reuse 程度還是無法明顯提高生產力。那麼究竟生產力要提高到什麼程度才夠?《Domain-Specific Modeling》的作者認為,大約要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,這樣的生產力才算是大幅躍進。後面會概略說明 DSM 是基於什麼理論方法來達到這個目標。

模型不能重複使用的主要原因,自然是因為大部分的軟體系統都不會完全一樣,不過,跟我們使用的塑模語言也有些關係。目前軟體社群普遍接受的塑模語言是 UML,這套語言是以標準化的圖形記號來表達軟體系統的各種面向,目的在於方便溝通。語言標準化的好處,是一旦多數人熟悉之後,彼此的溝通比較容易。相對的,它的缺點就是不提供特定領域的術語,因此往往無法精確表達特定領域的概念,而必須採用一些擴充的語法,如 stereotypes、tagged values 等等。如此一來,要從 UML 模型直接產生程式碼就會碰到許多困難。如上一篇引用過的,Booch 在 MDA Journal 發表的一篇文章裡這麼說:

「唯有當塑模的概念能夠直接對應到領域概念,而非電腦技術的概念,MDA 方能展現其完整價值。」
(The full value of MDA is only achieved when the modeling concepts map directly to domain concepts rather than computer technology concepts.)

也就是說,以 UML 為基礎的 MDA(Model-Driven Architecture),是以模型來推動軟體設計,而不是直接產生軟體程式,其目標在於表達領域概念。如果要讓 UML 模型直接對應到實作,仍然有其困難。就像前面說的,每一個軟體系統都不會完全一樣,都有需要客製化的部份,因此,如果要再進一步提高生產力,我們必須將軟體系統之間差異的部份再自動化一些;換言之,我們要將差異的部份用塑模語言描述,並且能夠直接轉換(或轉譯)成實作程式碼。

現在可以進入 DSD 了。

Domain-Specific Development

DSD 的一項特點是同中求異,其主要精神在於找出軟體系統中固定的部份以及容易變動的部份,並使用 DSL 來描述變動的部份;每當建置軟體系統時,就利用輔助工具將 DSL 模型轉換或轉譯成程式碼,再與固定的部份相結合,編譯成完整的系統。下面這張圖取自《Domain-Specific Development with Visual Studio DSL Tools》,它明白表達了上述概念:




所謂固定的部份(Fixed Part),指的就是手寫的程式碼,主要由軟體框架、模式(patterns)、以及一些共用元件所組成。整合(Integrate)的動作就是利用工具將模型轉換為程式碼,並與固定的部份相結合,最後再編譯為完整的應用程式。

其實這種概念四處可見,舉例來說,我們可以將個人電腦的主機板視為固定的部份,而主機板上面的 I/O 介面擴充槽、記憶體擴充槽、USB 連接埠等則是為了介接可變動的部分。假設有一種製造個人電腦的工廠,我們可能會開兩條生產線,一條專門生產高階工作站,使用的是高階顯示卡及高容量記憶體;另一條線則配接陽春的配備,生產價格較低廉的入門機種。

如果能夠將同類型的軟體系統之間的差異抓出來,並利用 DSL 工具加以自動化(產生程式碼),軟體生產線的理想境界或許終有實現的一天。

Domain-Specific Modeling

DSM 又比 DSD 更進一步(說更誇張或許比較貼切)。DSM 強調更完全的、更高層次的自動化,就像利用編譯器將程式碼編譯成可執行的軟體,當我們發現應用程式需要修改時,我們不會去改編譯過的二進位檔案,而是修改程式碼,然後重新編譯。DSM 的哲學也是如此:當我們發現設計出來的軟體有問題時,並不是直接修改程式碼,而是修改模型,然後利用工具將模型轉換成程式碼,再進行編譯。就像前面說的,《Domain-Specific Modeling》的作者認為,大概要有從組合語言跳到第三代語言(例如 C 語言)的明顯差距,生產力才算是大幅提升,而要達到這個目標,軟體系統的程式碼就必須完全從模型產生出來。下圖取自那 DSM 這本書的第一章,主要是展示 DSM 模型看起來長什麼樣子(圖形符號是自己定義的):



這張圖描繪的是研討會報名作業,圖中的方塊和箭頭等符號都不是單純的幾何圖形,它們都會對應到特定領域的概念及實作。我想,在能夠畫這些圖形符號之前,必定要費好大一番工夫,你至少得先定義 DSL、開發一套 DSL 塑模工具、還有程式碼產生器。此外,如果照 DSM 的作者說的,整個軟體系統的程式碼都是從模型產生出來,我很想知道當我把其中一個方塊的箭頭改指向另一個方塊會發生什麼事。

比 Hello World 再複雜一點的程式,或許可以做到完全透過模型來產生程式碼,對於許多複雜的商業軟體系統......我想我還需要更多想像力才行。相較之下,DSD 顯得實際多了。

註:就像 domain-specific languages 一樣,domain-specific modeling 並不是特定人或社群的專利;它只是強調特定領域的軟體設計理念和方法。這裡講的 DSM,指的都是《Domain-Specific Modeling》這本書所提的概念。

小結

DSD 和 DSM 的內涵雖然是軟體設計,但是從本文介紹的概念可以發現,它們也會影響軟體開發流程,因為塑模和產生程式碼的部份也在軟體開發過程中佔有很大的比重。除了簡單介紹 domain-specific design 的概念,文中也提到 UML/MDA 和 DSL/DSD/DSM 的基本差異。我想或許可以這麼說:UML/MDA 是以標準化為出發點,基本的理念是異中求同,先定義一套共通的語言,再利用它來表達各種系統的設計模型;DSL/DSD 則為同中求異,著重在塑模差異的部份,並將該部分的實作自動化,同時結合框架、模式、及工具來提升軟體開發的速度。

參考資料
  1. Domain-Specific Development with Visual Studio DSL Tools
    by Steve Cook, Gareth Jones, Stuart Kent, and Alan Cameon Wills. Addison Wesley, 2007.
  2. Domain-Specific Modeling: Enabling Full Code Generation
    by Steven Kelly, Juha-Pekka Tolvanen. Wiley-IEEE Computer Society Pr (March 7, 2008)
  3. Domain-Specific Modeling
    by Steve Cook. The Architecture Journal, October 2006.
  4. Domain-Specific Modeling with METAEDIT: 10 Times Faster Than UML
    by MetaCase, 2007.

開發人員的逆襲: Domain-Specific Languages

4/21/2008
本文最後的更新日期為 2008-4-26

軟體開發技術不斷改進,其背後推動的力量主要是為了應付軟體固有之複雜與善變的特性,而解決這些問題的其中一項重要關鍵,就在於抽象化(abstraction)。觀察整個軟體開發技術演進的歷史,可以發現它其實就是不斷提高抽象層次的過程。舉例來說,電腦只看得懂機器碼,因此組合語言便可視為第一次抽象化的成果--它讓程式設計師更容易撰寫程式碼。後來出現的高階語言,如 C 語言、Pascal 等,則又再提升了程式語言的抽象層次,直到我們現在使用的 VB、C#、Java 等,不難看出每一代程式語言的功能與抽象層次都不斷提升。然而,軟體系統的規模與複雜度也同樣與日俱增,那種訪談需求之後立刻埋頭寫程式的做法已經無法應付複雜的軟體系統,因此我們需要分解複雜系統的方法,將事物理出一番頭緒,並利用人類更容易理解的文字或符號來表達我們的設計。經過多年的努力與整合,軟體開發社群終於對如何表達設計有了共識:UML。

模型驅動

剛開始,UML 只是用來表達問題領域概念的工具,讓我們可以將軟體設計的想法以一套多數人都能理解的符號呈現出來,方便與他人溝通、討論。能夠做到這樣,UML 就已經是貢獻良多了。畢竟,軟體工程社群也是花了十幾年才逐漸達成此共識(如果從 1990 年代的 OMTOOSE、和 Booch'93 算起)。然而模型最終還是得透過程式語言實作出來,從抽象概念到具體實作,這當中有太多繁複的細節需要開發人員填補,於是,我們不斷在 OO 專案中討論究竟模型要畫到多細(文件要堆多高)才夠、table schema 究竟什麼時候才可以開始設計、要不要用 OR mapping...諸如此類的,其過程不只麻煩,開發成本也高。試想,要是模型畫好了,就能夠直接產生可執行的程式碼,不就一舉消弭了分析設計和實作之間的鴻溝嗎?對此問題,以 UML 為基礎所衍生的解決方案主要是 executable UML 和 OMG(Object Management Group;物件管理組織)提倡的模型驅動架構(Model-Driven Architecture;MDA)。

回想數年前,當時去參加一場 OOAD 課程,休息時間私下請教講師,他們的團隊是否真的有用那套 modeling 工具的 code-gen 功能(從畫好的 UML 模型自動產生程式碼),答曰沒有。那麼,現在的 UML 塑模工具是否已經進步到足以讓我們在實際的專案開發中使用 code-gen,甚至逆向工程(從程式碼產生模型)呢?支援 MDA 的工具,其模擬、驗證模型、以及產生程式碼的功能是否真的實用,且值得我們投資(購買工具、學習如何使用工具、以及描繪模型)?

關於這點,個人是抱持懷疑的態度。UML 原本就是用來表達較高層次的抽象模型,這模型是給人看的(而不是機器),其基本表示法在語意上並未精確到能直接和實作對應。然而,就算用上 stereotypes、tagged values、和 OCL(Object Constraint Language),如此是否就夠精確、完整,還是令人存疑;若要做到精確、完整的表達,是否又會弄出一套非常複雜的表示法(例如 MDA 的另一項關鍵技術:Meta-Object Facility;簡稱 MOF),也是需要考慮的因素。想用 UML 畫出可直接執行的模型,或者將模型直接轉成可執行的程式碼,距離實用的程度似乎還有一些距離。Booch 在 2004 年 MDA Journal 中說的一段話或許是最好的註腳:

「唯有當塑模的概念能夠直接對應到領域概念,而非電腦技術的概念,MDA 方能展現其完整價值。」
(The full value of MDA is only achieved when the modeling concepts map directly to domain concepts rather than computer technology concepts.)

如此說來,難道軟體開發的過程就無法再系統化、自動化一些嗎?既然以 UML 呈現的抽象分析設計模型不夠精確,那麼是否有什麼方法可以讓我們用精確的方式描述問題領域,並直接與實作接軌?相較於 UML 和 MDA,微軟給我們的答案是 DSL 與軟體工廠(Software Factories)。

什麼是 DSL?

DSL 是 Domain-Specific Language 的縮寫,中文譯為「特定領域語言」(或譯「領域特定語言」),也就是開發人員為了解決特定領域的問題所定義的專用語言。Karl Frank 認為,「domain-specific languages」可以泛指任何特定領域的語言,例如 UML、XML,甚至連 C#、Java 都算是特定領域的語言,因為它們都是針對特定目的(軟體開發),用於特定場合的語言,這是比較廣義的看法。不過,就軟體開發這塊領域而言,UML、C#、Java 可運用於各類型的軟體開發,所以我們通常將它們視為通用目的語言。另一方面,由於微軟近年大力提倡 DSL 及其支援工具,因此當我們提到 DSL 時(至少在討論 .NET 平台上的軟體開發時),通常是指微軟提出的概念和支援工具,而講到「特定領域語言」(domain-specific languages)時,則可能泛指任何特定領域的語言。

Martin Fowler 指出,DSL 並不是新觀念,早期 Unix 的 "little languages" 使用 lex 和 yacc 產生程式碼,以及在 LISP 中定義的語言,都是運用 DSL 技術的例子。微軟方面最早則是由 Charles Simonyi 開始研發支援 DSL 程式設計的工具,他稱之為「Intentional Programming」。為了明白區分,Fowler 將所有使用 DSL 的程式設計方式統稱為「語言導向程式設計」(Language-Oriented Programming),而將支援語言導向程式設計的開發工具統稱為「語言工作檯」(Language Workbench)[1]。

呼~真多術語。其實大概知道有這些名詞就好,簡單地說,就像程式語言需要編譯器和 IDE 工具,DSL 也一樣需要編譯或解譯的工具才有實質的意義。

DSL 範例

有在寫程式的人其實多少都有用到 DSL,例如曾經紅極一時的 Delphi,它的 .DFM 檔案就是一種特定領域語言。我們只要利用 Delphi IDE 提供的視覺化拖拉設計方式,將控制項放在 Windows Form 上面,並設定其屬性,IDE 就會幫我們在 .DFM 檔案中產生對應的描述,其內容與格式類似這樣:

object Form1: TForm1
Left = 192
Top = 107
Width = 509
Height = 462
Caption = 'Form1'
object DBGrid1: TDBGrid
Left = 60
Top = 80
Width = 341
Height = 293
end
object Database1: TDatabase
AliasName = 'DBDEMOS'
Connected = True
DatabaseName = 'testdb'
LoginPrompt = False
end
end

當然,我們也可以為自己量身訂作一套特定領域語言。舉例來說,假設我們要設計一款射擊遊戲,此遊戲的每一關都有一隻魔王(boss),而我們希望用一個外部檔案來定義魔王的運動路徑,例如:

Stage: 1
BossClass: Dragon
InitialPosition: 400, 300
MovingPath1: (3,2,10) (-4,2,30) (5,-1,30) ......
MovingPath2: (7,-2,5) (12,0,10) ......

第 1 列到第 3 列分別描述了第幾關、魔王的類別名稱、初始位置,第 4 列則為魔王的第一種移動路徑,第 5 列是另一種移動路徑,其中每一對括弧中的三個數字分別代表 x 偏移量、y 偏移量、以及在該位置持續多少個時間單位。

為了處理魔王的運動路徑,我們自行定義了一種語言來描述這些資料,這就是我們的 domain-specific language。

上述資料也可用改 XML 格式來描述,例如:

<Stage>
<Number>1</Number>
<BossClass>Dragon</BossClass>
<InitialPosition>400,300</InitialPosition>
<MovingPath1>(3,2,10) (-4,2,30) (5,-1,30) ......</MovingPath1>
<MovingPath2> (7,-2,5) (12,0,10) ......</MovingPath2>
</Stage>

其實我們可以發現很多軟體技術都是採用 XML 來描述特定領域,例如 JSP 和 ASP.NET 應用程式的組態檔、Windows Presentation Foundation 使用的 XAML 等都算是特定領域語言的應用。

以上所提的例子都是純文字的 DSL,但是它也可以是圖形符號。文字型的 DSL 好處在於容易給電腦處理,例如字串的搜尋、代換,以及文字內容的差異比對、合併等等。圖形式 DSL 的優點則是一目瞭然,很容易掌握整個模型的概觀以及各元素之間的關係。微軟的 DSL 是偏向以圖形符號的方式呈現。

誰要使用 DSL?

DSL 既然是處理特定問題領域的語言,除了程式開發人員之外,領域專家(domain expert)也必須會用。此時外部 DSL 就明顯佔優勢:你可以為特定領域定義一套比較簡單的,甚至連 end-user 都能夠自行修改的語法。DSL 擁護者認為(希望),將來一定會演進到由 end-user 自行修改領域邏輯的地步,屆時程式開發人員大部分時間都會用在開發 DSL 支援工具上面,而不是與不斷變動的需求奮戰。這種境界似乎太過美好,好到不夠真實。然而就算這一天真的到來,也不代表開發人員的工作內容將有一百八十度大轉變,或程式設計師會突然丟掉飯碗--軟體開發的工作總是需要優秀、嚴謹、細心的程式設計師。不過,有了 DSL,那些容易變動的軟體需求或許能夠大部分交給 end-user 自行掌控,讓他們也能調整軟體的行為;能夠由 DSL 控制的部份愈多,軟體的維護成本就愈低,開發人員也夠將心力投注在其他更有價值的工作上面。這或許是一個理想境界,但是退一步想,即使只有開發人員會使用 DSL,對提升軟體開發的生產力應該也有不少幫助。(怎麼個有幫助法?這部份等下次再寫一篇文章討論吧。)

在決定是否使用 DSL 時,還有一些問題必須考慮。首先,問題領域是否複雜到值得花費人力、時間來定義一套 DSL?如果只是一般的小問題,其實就用不著大費周章定義一套 DSL,至於哪種問題算大,哪種問題算小,這恐怕還得看每個 case 的情況,以及靠經驗來判斷。
Good judgment comes from experience. Experience comes from bad judgment.
Jim Horning


其次,如果 DSL 由領域專家負責撰寫,領域專家與程式設計師之間的溝通可能會是比較棘手的問題。而且,在結構化設計與物件導向設計世代交替時,系統分析師已經歷過一段學習 UML 的痛苦期,現在又要他們學習另一套(甚至多套)DSL,這恐怕會造成不少反彈。

開發人員的逆襲

UML 最近幾年在軟體工程領域可說是引領風潮,然而,隨著時代進步,更新更好的開發技術會不斷出現,UML 的地位也勢必面臨挑戰。這應是好事,至少可以提醒我們:到底 UML 對軟體開發帶來哪些好處?我們是否過度使用、推崇、甚至迷信 UML,以至於碰到任何問題都只想著該用哪種 UML 圖來表達?正如 Abraham Maslow 說的:「當你手中只有鐵槌,你會傾向將所有碰到的問題看成釘子。

個人的看法還是以實用觀點出發,在分析設計時,碰到覺得適合用 UML 圖形表達的,當然還是用 UML,但不用太在意如何第一次就把圖畫得盡善盡美,以及設想如何好好的保存這些圖,以免大部分的注意力侷限在畫圖這件事情上,原本分析設計的目的反而被模糊掉。

如果您有使用 UML,我想您應該會同意 UML 仍有它擅長的地方(表達較高層次的抽象概念),而且它仍然有持續擴充的機會。畢竟,UML 已經是廣為接受的表示法,在既有的基礎上改進,總是比另創一套新的語言更省力,這也是某些 UML 擁護者的看法。

從塑模的角度來看,UML 是從比較高抽象層次的角度出發,嘗試以通用的表示法來呈現系統分析設計的結果,然後逐漸細化,銜接到軟體的實作。DSL 則是強調與實作更緊密的整合,雖然它也是一種塑模語言,但我覺得它是比較從程式開發人員的角度出發,一種由下往上銜接的嘗試。

這樣的嘗試能否成功?

從現有的文章、討論、和書籍來看,微軟大約是從 2003 年開始研發推廣 DSL 和軟體工廠的概念,到現在已過了四個年頭,從 Visual Studio 對 DSL 的支援,我們可以看出微軟正逐漸落實軟體工廠的理念。此方法若能廣為軟體開發社群接受,想必又是一次典範轉移。至於結果如何,還是讓時間來回答吧。

小結

DSL 的目標很明確,就是要協助軟體開發人員提高生產力。然而,要吸引更多軟體開發人員的目光,需要的是強大的輔助工具和令人眼睛為之一亮的殺手級應用。在這方面,微軟正不斷地加強 DSL Tools,而且微軟一向強調 eat your own dog food(吃自己做的狗食),再加上愈來愈多專家(如 Martin Fowler)的投入,其後續發展頗值得我們關注。

此外,如 Steve Cook 所言,DSL 只是協助軟體開發的其中一項工具,我們還必須有靈活的(agile)開發流程(process)、軟體框架(framework)、以及模式(patterns)的搭配,方能大幅提高生產力,而其最終的理想目標,是讓軟體開發也能像製造業的生產流程一樣,建立具有多條產品線的軟體工廠 [2]。關於軟體工廠的概念,可以參考 Jack Greenfield 的文章 [3];他和 Keith Short、Steve Cook、以及 Stuart Kent 等人合著的《Software Factories》有更完整詳細的介紹,中研院的吳信輝先生也曾發表過一系列「細說軟體工廠」的文章,可以用 Google 找到一些。

備註
  1. Martin Fowler, "Language Workbenches: The Killer-App for Domain Specific Languages?"
    URL: http://martinfowler.com/articles/languageWorkbench.html
  2. Steve Cook, "Domain-Specific Modeling and Model Driven Architecture," MDA Journal, January 2004.
  3. Jack Greenfield, "Software Factories: Assembling Applications with Patterns, Models, Frameworks, and Tools."
    URL: http://msdn2.microsoft.com/en-us/library/ms954811.aspx

VSTS 把單元測試變簡單了!

4/17/2008
在《軟體工程與 Microsoft Visual Studio Team System》的第三章,裡面有提到一個與單元測試有關的真實案例,就從這個例子說起吧。我把這段故事貼上來:

「這個故事發生在2003 年,當微軟嘗試定義Visual Studio Team System 的需求時,對某一家銀行所做的訪談。在某個早晨舉辦的開放式焦點團體會議中,微軟團隊詢問他們開發軟體的一些實務作法,其中特別問到了有沒有實施單元測試。他們說單元測試對這家銀行的所有開發人員來說根本就是家常便飯,而且每次簽入(check-in)程式碼之前,都一定會先進行單元測試。

到了下午,微軟有一位負責軟體易用性的工程師就實地觀察了他們其中一位開發人員的工作情形(這也是它稱為情境訪談的原因)。這名開發人員寫了一些程式,這當中也執行了幾次簽入程式碼的動作。幾個小時之後,易用性工程師問道:「我看你做了好幾次簽入動作,可是你有做單元測試嗎?」「當然有啊!」他立刻回答:「我在每次簽入之前都有按F5 ── 這個動作就是單元測試啦。」(如果你沒用過 Visual Studio 的話,F5 就是編譯的快速鍵,跟測試一點關係也沒有。)之前他們自己陳述的單元測試實務根本就從沒發生過。在設計 VSTS 的時候,我們把這種誤解的現象視為一個機會,我們要把單元測試功能做到像這家銀行的開發人員所認為的那樣簡單、好用(見第 6 章「開發」)。」

沒人在乎單元測試?

也許您已經非常清楚單元測試的概念,甚至可能已經實戰經驗豐富了。然而,我卻碰過許多次類似的情形,誤把除錯當作單元測試;在接觸過的幾個專案的計畫書中,都有看到「單元測試」項目,裡面寫得很像那麼回事,可是一見面詢問之下,馬上就露餡兒(喔,原來他指的是單步除錯 o_O)。

難道就像〈沒人在乎軟體工程〉一樣,也沒有人在乎單元測試嗎?如果單元測試真的這麼好,為什麼大家口中經常提到的單元測試,卻僅只停留「口頭練習」階段,而沒有實際用在專案開發呢?

不過,這只是個人憑感覺的臆測,並沒有統計數據顯示軟體業有多少人瞭解或真正實行單元測試。搞不好我碰到的例子正好就是那少數中的少數罷了。

程式設計師為什麼不做單元測試,這個在 Test-Driven Development 和 Extreme Programming 相關的書籍、文章裡面都討論很多了,這裡就不細談,只分享一點自己使用 VSTS 撰寫單元測試的經驗。

先寫程式?先寫測試?

許多測試驅動開發和 XP 的擁護者都提倡先寫測試,再寫程式。由於先寫測試程式的緣故,這些測試當然不會通過,於是你就會撰寫實際的程式碼讓測試通過。等測試通過了,你又再寫更多測試,然後再寫更多程式......如此反覆循環,你的應用程式就逐漸完成了。可是,究竟有多少人能接受先寫測試的做法呢?或許先寫測試才是讓程式設計師不想寫單元測試的原因?

其實不用這麼煩惱,如果覺得心中已經浮現一些軟體設計的 idea 或架構,先寫點程式又有何妨?寫了一點程式之後,總會碰到一些特別重要的地方(例如交易處理或者複雜的演算法),需要更強大的防護網來確保程式能夠正確執行,這時候再加一點單元測試來確保某個底層或核心的處理函式正確無誤。這樣不也挺好?

我最近便是用先寫一點程式,再寫一點測試的反覆循環方式,逐漸完成一個 .NET 類別庫的設計。整個設計和程式撰寫的過程可以說相當愉快。當然啦,這有賴於 Visual Studio Team System 提供方便的單元測試功能。

大部分時候,我會先在紙上畫很粗略的類別圖(有時甚至連圖都稱不上,只是 idea 的呈現),等到覺得差不多該付諸實現時,就開始撰寫程式。我會一直寫,直到完成比較重要的 methods,再用 VSTS 幫我產生單元測試的程式碼。只要在想要測試的 method 上方點滑鼠右鍵,再點「Create Unit Tests」就行了。如下圖:

如果是第一次產生單元測試的程式碼,VSTS 會先幫你建立一個單元測試專案,所有單元測試的程式碼就放在這個測試專案裡(當然你也可以建立多個測試專案)。上圖的動作會令 VSTS 幫我產生 BrailleConverter.ToBrailleWord 方法的測試程式碼,你會得到像下面這樣的測試程式碼:


///
///A test for ToBrailleWord (string)
///

[TestMethod()] public void ToBrailleWordTest()
{
BrailleConverter target = new BrailleConverter();
string text = null; // TODO: Initialize to an appropriate value
BrailleWord expected = null;
BrailleWord actual;

actual = target.ToBrailleWord(text);
Assert.AreEqual(expected, actual,
"Huanlin.Braille.BrailleConverter.ToBrailleWord did not return the expected value." + "");
Assert.Inconclusive("Verify the correctness of this test method.");
}

VSTS 產生的測試程式碼提供了一個很好的起點,只要稍加修改就行了。以下是實際修改後的測試程式碼:

///
///A test for ToBrailleWord (string)
///
[TestMethod()]
public void ToBrailleWordTest()
{
BrailleConverter target = new BrailleConverter(brTbl);
// 測試結合韻.
string text = "我";
BrailleWord expected = new BrailleWord(text, " ㄨㄛˇ", "2420");
BrailleWord actual = target.ToBrailleWord(text);
Assert.AreEqual(expected, actual, "BrailleConverter.ToBrailleChar 測試失敗: " + text);
// 測試單音字.
text = "智";
expected = new BrailleWord(text, "ㄓ  ˋ", "AC8234");
actual = target.ToBrailleWord(text);
Assert.AreEqual(expected, actual, "BrailleConverter.ToBrailleChar 測試失敗: " + text);
// 測試標點符號.
// ......略
}


要執行測試時,只要從 VSTS 主選單點選 Test > Start Selected Test Project with/without Debugger,或直接從工具列點選測試鈕就行了。測試的結果就像建置專案的結果一樣會顯示在 VSTS 下方的視窗裡。參考下圖:
只要是測試通過的項目,就會像圖中一樣顯示綠色打勾的圖示。測試失敗的項目會是紅色打叉的圖示,測試結果不確定的項目則是黃色的警告圖示。

每次只要應用程式的 code 有修改,我就會去執行一下單元測試--反正只是按個鈕嘛,一點也不費力。當我看到一整排綠色打勾的圖示,我知道這次動到的程式碼並沒有把原有的功能破壞掉,我可以很放心的繼續寫其他程式。如果有出現紅色圖示,我也能夠透過單步除錯單元測試程式碼來迅速找到問題的原因--這實在是很棒的 bug 防護網啊,不是嗎?

因此,不管你是習慣先寫測試,還是先寫程式,VSTS 都能讓你很方便的完成單元測試的撰寫與測試工作。VSTS 真的把單元測試變簡單了。

書摘:《研究科學的第一步》(Advice for a Young Investigator)

4/17/2008
中文書名:研究科學的第一步
英文書名:Advice for a Young Investigator
作者:Santiago Ramon y Cajal
翻譯:程樹德

「如果當初進入研究所時就看過這本書,或許可以少走一些冤枉路。」是我讀這本書的時候,心頭偶爾浮現的想法。書中提到許多做研究應有的態度跟觀念,但不會讓人有喋喋不休、令人生厭的感覺。作者就像和藹的長者,對後進不厭其煩地提點、說明,深怕新手走岔了路。

不過,中文版有不少句子讀起來有些彆扭,例如:

「偉人有時是天才,偶爾是兒童,可是永遠不完全。」 (p.53)
「如果我的努力只是添加一點小細節,那到底會有什麼幫忙呢?」 (p.58)


很少看到或聽到「會有什麼幫忙」這種說法,「會有什麼幫助」不是很平常的口語嗎?

「很明顯,這種冷酷的儀器狂,不能對任何人有好處,對自己也是個大傷害。」 (p.154)

「不能對任何人有好處」的英文可能是 Couldn't benefit...。一般我們會說:「對任何人都沒好處。」

潘震澤先生也針對此書寫了一篇比較專業的譯評,但這篇譯評僅針對本書的引言部份做討論,未就各章的內容加以評析。

雖然有些缺點,但本書依然值得推薦給有心做研究的人(要是出版社能重新校對潤飾,發行第二版就更好了)。

以下是一些書摘和隨手筆記:

=================<>===================

第一章:引言

我們基本上沒辦法透視自然現象的真理,或者自然現象的本質。因此,我們的立場不只是假設自己無知,甚至無可避免的要假設自然是不可知的,宇宙的「本質」並不是我們科學家所能夠知道的。......諸如生命的起源?物質到底是什麼東西?運動到底是怎麼產生的?人的自覺意識如何出現?我們必須承認,人類的心智,基本上沒辦法解決這些艱難的問題......大腦的產生,並非讓我們發現事物的終極原因,反之,要讓我們能夠決定事物的近因,以及事物之間不變的關係。我這樣講,似乎要限制人的心智能力。其實,人的心智能力所能達成的工作,已經極其龐大了。我們人類的頭腦既能讓我們了解世界的能力,這樣就已經產生了極大優勢,讓我們可以改造環境,改造世界,來改進人類的生活。因此,縱使不知道事物的本質,我們能夠做的,還是很多呢。 (p.42)

我們該知道,其實最傑出的發現,根本不依靠邏輯的演繹關係,學者完全不需要學任何邏輯....因此,與其看空洞的研究方法,還不如讀偉大的科學或開拓者的作品,例如:伽利略、克卜勒、牛頓......。 (p.45)

注:如同讀書要讀原典,會比看那些後來延伸詮釋的書籍更有價值,更能啟發思考(還是原汁原味好)。

叔本華在《意志與表象的世界》 (The World as Will and as Representation) 這本書裡面談到邏輯時,他說:「最好的邏輯,就是在認真探究時,應該把全部邏輯規則拋棄。」他又說:「想要在實際的研究裡面運用邏輯,就像是學走路時,先研究力學的定律一樣。」 (p.49)

第二章:坑殺新手的陷阱

我認為聰明的年輕人,其心中最不幸的觀念,就是對偉大科學家過度地崇拜。另一個影響年輕人的大問題,就是認為很多問題無法被我們解決,甚至連攻擊它都沒有辦法,因為年輕人自認能力不足。以上是年輕人最重要的錯誤觀念。......新手閱讀天才所寫的作品時,可能會迷戀於他優雅的文筆風格,以及談理論時漂亮的戲法,如果新手能夠逃脫這天才的魔力,走進實驗室裡去,設法確定前人的觀察是否真確,檢驗這麼有趣的觀念是否能夠重複實現,那麼,新手就能逐漸怯除他對英雄的崇拜,自信心也就逐漸產生。 (p.53)

我們不要在偉人的面前,自覺卑微自覺渺小,我們要讓新手瞭解一個很殘酷、可是無可避免的定律,那就是:新手們的命運,新手們的事業,如果想要飛黃騰達的時候,那一定要能夠破壞跟減損偉人之聲望方能達成。 (p.55)

法國哲學家盧梭講的尖刻話很能令人傷心,可是卻很真實:「世上不可能找到一個有智慧的人,他不努力去吹捧自己的謊言,倒去鼓吹別人所發現的真理。」(p.56)

注:「很能令人傷心」......試改譯成這樣看看:法國哲學家盧梭說過一句尖刻話:「世上沒有一個智者不努力吹捧自己的謊言,反倒去鼓吹別人發現的真理。」這話雖令人傷心,卻很真實。

剛畢業的學子,腦子裡有另一個錯誤的觀念,他們說:「各門科學最重要的東西都已經被發現了,都已經被鑽研得很清楚了,如果我的努力只是添加一點小細節,那到底會有什麼幫忙呢?聰明努力的觀察家,已經在麥田裡把麥子都收割了,我是否只能做拾穗的工作?......」這說法的真相,其實是「怠惰」偽裝成「謙虛」,「懶散」偽裝成「卑微」。 (p.58)


我可以很公平地這樣說,一般來講,沒有任何科學問題是已經被做得光光的,而不能再重新去探討。相反的,人已經給問題搞得筋疲力竭了所以不願再繼續去探討,不願再去深究。......其實,我們之知識是非常片段而瑣碎,因此,甚至最被精深探討過的課題,裡面仍有很多未知的新發現。 (p.60)

注:「我們之知識」==> 「我們的知識 」

如果,新手願意蒐集更精細的資料,從事這些精明睿智的開創性科學家所不願做的事,那麼我可以保證,在新手尋找瑣碎的細節時,最後可以訓練他的分析能力,可以讓他有強之分析力,以及觀察力,用這兩種力量及他的細密證據,可以成功地解決重要的問題。......還有,我們一定要記得,我們人所認為的所謂重要不重要,偉大或者渺小,其實是基於我們人類觀點所產生的錯誤,在自然裡面沒有高等或低等,沒有優秀或惡劣,也沒有主要或次要的關係。 (p.61)

注意細節以及重視方法跟技術,這兩件事有極其重大深遠的影響。 (p.62)

因之總結來說,世上沒有小問題。表面上看起來很小的問題,其實是我們所不了解的大問題,真的!宇宙內並沒有知識份子所看不起的小細節,有的只是頭腦不靈光的學者,他們渺小的智能,沒辦法參透這無窮無盡的宇宙.......在考慮大自然運作的機制中,淺薄的人把某些部份看作重要,把某些當作次要,可是對有創見的思想家而言,他把大自然的事物區分為已經瞭解的,或者不太瞭解的,而不管這些東西是否大小,是否對人類有立即的用途,沒有人能預測某件事物在未來有多重要。 (p.63--64)

我們攻擊自然界各問題時,只考慮這問題是否值得我們去研究,不要考慮到這問題是否有應用價值,考慮應用價值時,會干擾我們的專注力,甚至減弱我們的分析力。 (6)

有些人要解釋他為什麼失敗又沮喪,就說他沒有做科學的能力。......只要學生相信,好的教育仍然能夠創造人才,只要他能夠灌注很長的時間,來分析一個特定的科學題目,甚至普通心智能力的學生,都可以產生一些新成果,都可以享受科學的樂趣。......如果缺乏天生的心智能力,其實可以用「努力工作」跟「專心致志」來彌補。我們可以說,工作可以替代才能,甚至可以這樣說:工作可以創造才能。 (p.69--72)

第三章:需要何種心智能力?

當新手第一次讀經典名著的時候,並不是每一個人都能發現書中的缺陷跟錯誤,可是,如果對名著太過於尊敬,就像是所有激情狀態一樣,都能防止頭腦對之進行批判性評價,如果讀了一次感覺到頭腦很累,沒辦法領悟,也沒辦法完全吸收,那麼休息幾天吧!幾天後用冷靜的頭腦跟清醒的判斷力,再讀第二次或第三次,然後逐漸地,書中的缺陷就變得愈來愈明顯,而裡面不合邏輯或是錯誤的地方,也被揭發出來;看起來漂亮的假設,失去了它的權威性,揭發出它們非常不穩固的根基,我們終於能不被他的文采所迷惑,換言之,我們終於能逐漸瞭解,對這部經典作品,吾人不再是盲目的崇拜者,而是這本書精明的裁判,這個時候,研究就可以開始了,可以用更好的假設取代作者原有的假設,讓書中每一件事情都經過你嚴厲的批判。

沒有自信心的人,不知道專心致志的神妙力量,這一種大腦的偏極化也就是涉及你對事物的全盤感受,能夠讓判斷變得更精緻,能夠豐富你的分析能力,也能夠刺激建設性的想像,而且因為把全部的理性及推理力量放在問題上面,使人能夠發覺以前看不到的事物間的微妙關係。......長久時間的「專注」能夠讓我們的心靈在最複雜的問題中,也能夠感覺到一絲光線。

第四章:生物研究的新手須知

法國科學家拉普拉斯(Laplace)曾經指出:「所謂發現這種事,其實是把以前不相關的兩個觀念連在一起而已。」 (p.113)

一旦一個人想要得到百科全書似的廣博知識,那他的研究立刻就會觸礁,因為一個缺乏秩序的心靈,會想要不停的獲取知識,而這種心靈是好動的,沒有紀律,而且不能專心。......擁有這種心靈的人,可以變成一個偉大的作家,非常令人快樂的閒談家,甚至是一個有名的演講家,可是這種人不可能在科學上有大發現。 (p.117)
=====================================
購買本書

書摘:戴明的新經濟觀(The New Economics)

4/17/2008
在翻譯《軟體工程與 Microsoft Visual Studio Team System》這本書的過程當中,除了加深我對軟體工程與 Visual Studio Team System 的瞭解,另一個讓我收獲很多的,是每一章最後附的參考文獻。作者 Sam Guckenheimer 在軟體開發方面的經驗非常豐富,而從他引用的相關書籍和文獻來看,可以發現他不僅是軟體工程與 VSTS 的專家,對其他知識領域也涉獵廣博,包括心理學、科技管理、研究製造、經濟學......等等。透過這些參考文獻,也讓我發現一些頗有意思的書。舉例來說,書中對於一些專案管理和變異(variation)的觀念,主要是源自《戴明的新經濟觀》書中的理論。我也挺喜歡這本書,這裡就做個簡短的書摘供大家參考(您也可以參考網路上的另一篇書摘)。

書名:戴明的新經濟觀
作者:W. Edwards Deming
譯者:戴久永
出版:天下文化

---------------< 書摘開始 >-----------------------------------------------

美國人的問題在於教育以及如何發展重視學習的文化。(p.8)

注:台灣也是啊!Orz

顧客不會發明

大家都說要符合顧客的期望。事實上,顧客的期望乃是由你與你的競爭對手所塑造,顧客學得很快。(p.9)

注:例如,是顧客要求軟體廠商發展即時通訊軟體,還是廠商先開發出來,人們覺得好用才開始普及?

高階管理者該為品質負責

公司產品的品質,不可能高於高階管理者所設定的品質水準。(p.20)

注:如果主事者與開發人員在軟體開發方面的理念不一致,或者不了解開發人員為何要這樣做,以及那樣做對品質有何影響的時候,開發人員恐怕很難得到上頭的認同與許可,去做他們認為該做的事。因此,主事者必須對軟體開發的本質、概念、與實務作法有一定程度的了解,才能將開發的方向導正,並確保軟體的品質。所以,結論就是.....不只是開發團隊成員,各位現任(或未來將升任)的軟體公司主管、CIO、專案經理們, 請務必也買一本《軟體工程與 Microsoft Visual Studio Team System》回去看呀! (shame on me ^_^ )

廢除考績制度

將員工排等級,正顯示了管理者的失職。在考績制度下,所有人的目標都是討好上司。結果將會導致士氣低落,品質受損。因此把員工評等分級,分門別類,對於改善工作並沒有任何幫助。

錯誤的企管教育-數字化目標與結果導向管理

數字化目標會導致扭曲和作假,尤其是當系統根本無力達到目標的時候,更有此可能。每個人都會設法達成被分配到的配額(目標),但卻並不對由此所導致的損失負責。(p.37)

注:《軟體工程與 Microsoft Visual Studio Team System》書中也有舉出一些類似的例子,像是:程式設計師故意埋下很多 bugs,並由自己找出這些 bugs,以達到 bug 發現率的數字化目標。報表上的數字看起來是達到目標了,可是實際的產出和績效卻一點也沒有長進。

管理者其實應該專注於流程的改善,而不是設定數字化目標。(p.38)

採用成果導向的管理,帶來的困擾是更多而非更少。......以成果為導向的管理針對結果採取行動,也就是認定結果來自特殊原因。其實重要的是針對造成該結果的原因--也就是系統--下功夫。(p.39)

每一位管理者都認為自己是全力以赴。他們確實如此,而這也正是問題所在。他們的「最佳」,是立基於現行的管理系統之下,而這個管理系統,正如我們前面所指出,會引起難以估算的巨大損失。如果沒有外來知識的協助,管理者的努力只會把我們目前所陷入的坑愈挖愈深。(p.43)

注:Do the right thing. 往錯的方向努力,只會愈陷愈深,導致更大的災難。然而系統本身無法察覺自己的問題,需藉由外來知識(即作者專章介紹的淵博知識體系)的協助才能導正方向。

建立系統的觀念

如果說金字塔型的組織圖真的傳遞了什麼訊息給員工的話,那就是:每個人首要的工作就是取悅上司(以便得到好的考績)。......金字塔的組織圖確實具有破壞系統的作用,因為它促使組織的部門各自為政,形成個別的利潤中心,以致破壞了系統。(p.70)

讓人人了解自己的貢獻

「工作說明」(job description)不是描述動作、做這個、做那個、這樣做、那樣做,還應該增加說明工作的用處,以及工作對整個系統目標的貢獻。(p.73)

內在動機 v.s. 外在動機

將個人、小組、部門、地區排等級,並發獎金給排名在前者,將會打擊所有相關人員的士氣,包括受獎者在內。......無論是小孩或大人,如果必須一直關心自己的表現,以爭取好成績和獎狀,就不能享受學習的樂趣。.....如果必須與他人爭排名,沒有人能夠享受工作樂趣。 (p.122)

注:薪水固然重要,但興趣與工作樂趣更重要。若僅僅為了高薪而跳槽,很可能因此失去了一個很好的工作環境與發揮個人專長的舞台。

人員的管理

不准你爭辯的老闆,不值得你替他賣命。(p.139)

為求縮短開發時間,一般的作法是倉促地完成開發,結果卻發現個別部份無法組合起來,或是突然有更新更優秀的設計點子出現。於是一切再回到原點,重新開始。結果浪費時間,成本提高,最終產品也不如預期。 (p.152)

縮短開發時間的秘訣,在於多下一點功夫在最初的階段上,同時要研究階段間的相互影響。在愈早階段花愈多的努力,所獲得的利益會愈大。 (p.152)


注:軟體開發也是如此。倒不是說我們應該在初期就過度地分析或做過多的前置設計 (up-front design),而是指在初期就應該審慎規劃、分析主要風險、以及做好架構面的考量。把一開始的路鋪好,以後會走得更順。
---------------< 書摘結束 >-----------------------------------------------
購買本書

時程膽小雞

4/17/2008
雞的下場軟體工程與 VSTS》的第九章是在討論專案開發時經常碰到的疑難雜症,以及如何利用 VSTS 的統計報告來發現、診斷這些問題。其中談到一個挺有意思的術語:「時程膽小雞」(schedule chicken),它指的是開發人員因為無法承受時程的壓力,而做出一些敷衍、耍小手段等扭曲的行為,好讓自己的工作看起來已經達到預定進度了。

參與過團隊開發的讀者也許也曾碰過「時程膽小雞」的情形。比如說,在開專案進度會議的時候,可能每個人都說自己的進度沒有落後,其實大家都在等別人承認進度落後。更誇張的,可能還有人會故作姿態:「如果你那邊還要再一兩個星期才能完成,我這邊可以等,我沒問題啦!」如果你回答兩天內就可以完成,他可能就開始緊張了。

再舉一個從別處看到的「時程膽小雞」例子。假設程式經理宣佈某一天必須實施「程式碼凍結」(code freezing),從那天開始不能再增加新的程式,只允許修改有問題的程式碼。於是程式設計師們基於畏懼時程的心理,就算到時候無法如期完成預定進度,還是會在程式碼凍結日的前一天簽入(check-in)所有的程式碼,但這些程式碼可能都沒經過測試、甚至無法執行或建置(管它的,先簽入再說,反正凍結之後是允許修改的)。

個人以為,如果程式設計師沒有勇氣抵抗時程的壓力,而採用敷衍了事或吹噓進度的作法,最後吃虧的還是自己,當然團隊也是。不過話說回來,如果我上班時偷雞摸魚,四處上網看"風景圖"、聊八卦,等到工作時程快要到 deadline 時才開始處理正事,這種情況可就不能說自己是在發揮抵抗時程壓力的勇氣了。

p.s. 以上的例子取自這篇部落格文章:Schedule Game #1: Schedule Chicken

公開透明的專案開發狀態

4/17/2008
上次簡單介紹了《軟體工程與 VSTS》的中心思想,這回我想和大家分享另一個貫穿本書的要旨--公開透明的專案開發狀態。

當我在閱讀和翻譯這本書時,作者在書中舉的一些例子或實務建議經常讓我聯想到過去的專案開發經驗,「公開透明的專案開發狀態」就是其中一個。這聽起來似乎不是什麼了不得的新概念,可是就像作者在書中引述佛洛伊德的話:「天經地義的事情反而沒人會把它說清楚、講明白。」這看似再明白不過的道理,不知有多少人認真思考過並付諸實行?

如果你是一名程式設計師,在開發專案時,是否曾有一種見樹不見林的感覺?這種感覺就好像走在森林裡,你知道自己正往哪個方向走(或者其實是別人告訴你該往哪裡走),可是卻不知道路還有多遠、最終目的長什麼樣子。如果是這樣,你還會積極前進嗎?如果你是 CIO、PM、或 team leader,你希望只有自己能掌握專案的完整資訊嗎?你的管理風格是傾向讓小組成員聽命行事,還是讓他們隨時了解專案的狀態、主動積極解決專案的問題?

考慮另一種情況,當你把客戶反應的問題逐一測試並確認之後,交給程式開發人員處理,你是否希望能隨時知道那些問題的處理進度(以免客戶問你時支支吾吾無言以對),但是又不想一直去叨擾開發人員?如果你是 PM,你是否希望能夠隨時知道目前的專案開發進度?在哪個環節出現瓶頸而拖慢開發速度?誰的工作負擔比較輕可以來支援這個某項任務?......

以上問題的答案,就是公開透明的專案開發狀態。

讓所有成員都能看到專案的所有開發狀態,不僅能夠促進專案成員主動積極的工作態度,同時也能提高團隊合作的效率。如此,團隊的運作將不再是檯面下的動作(這裡並不全然指"小動作"),而是完全的開誠佈公,從而建立一個向心力強、彼此互信的團隊。確實,互相信賴真的是維繫團隊成員的關鍵。試想,少了信賴基礎,團隊成員彼此相互猜忌,工作效率怎麼會好?(為什麼我的工作比較多?為什麼反映給他的 bug 都遲遲未解?到底專案進度落後多少?待會兒的檢討會議要怎樣避免被他人攻擊....)

了解公開透明的重要性之後,接下來的問題便是:How?我們要如何實現這個目標?

VSTS 把專案所有的工作項目都儲存在一個共用的產品工作清單(product backlog)裡面,所有的專案成員都能透過 VSTS 用戶端工具(包括 Team Explorer、Excel、Project...)存取這份工作清單的內容和狀態。註:所謂的工作項目(work items),包括 bug、風險、要完成的軟體功能、以及其他開發相關的工作。

不僅如此,VSTS 能夠維護開發流程中的各個工作項目之間的關連性,同時會把工作項目的狀態與歷史紀錄保存在度量資訊倉儲裡面,以產生各種專案開發狀態的統計圖表。這樣一來,所有團隊成員都能隨時檢視、發現問題、並主動解決問題--換句話說,把軟體開發的整個過程都透明化了!

附帶一提,SCRUM 軟體開發流程是單一 product backlog 概念的先驅,如果您對它有興趣,可以到這個網站逛逛:http://www.mountaingoatsoftware.com/scrum/

如果對敏捷測試有興趣,這裡有教學課程可以參考:Agile Testing Tutorial

增值與減工思維模式(Value-up and Work-down Paradigm)

4/17/2008
軟體工程與 Microsoft Visual Studio Team System》的第一章是「增值思維模式」,這次就先和大家分享個人對此主題的了解與心得。

以往在開發專案時,大都是先與客戶(或主要的利害關係人)討論出專案的目標與粗略的範圍(scope),然後透過與使用者訪談的程序,訂出比較細的專案範圍與功能需求,最後得到一份完整的功能清單(至少當時雙方認為應該夠完整了)。這份功能清單將影響往後的開發計畫決策,包括人力、時間等資源的安排,團隊也是以完成這份清單中所有的功能為目標。當開發團隊把功能清單裏的項目全部完成,就視為這個專案已經完成了。

但問題是,需求往往在一開始並不是那麼明顯。許多時候,使用者都是在看到實際執行的軟體畫面時,心中才開始浮現它所想要的軟體應該長什麼樣子。可是當初卻做了一堆計畫,團隊成員、時間也都安排好了,怎麼辦?比較好的情況是,雙方各讓一步,若需求有大幅的變動(例如增加新的子系統)就延長交貨期限,要不然就增加預算或人力。可是結果到最後往往雙方都不滿意,因為需求範圍的一再改變與擴大,將使開發團隊失去耐心,最後只好以合約書的內容拒絕變更需求;客戶也一樣不滿,因為他花了錢卻沒有得到他真正想要的東西。

寫到這裡,突然想到有一種軟體生命週期是這樣的(摘自《我懂了!專案管理》):

計劃開始 -> 火熱投入 -> 理想破滅 -> 一片混亂 -> 找代罪羔羊 -> 處罰無辜的人 -> 無功之人晉升 -> 限定各項要求

我想許多人應該也有類似的經驗吧(也許沒那麼誇張),我們總是感嘆:為什麼軟體這麼難做?!

前面舉的例子,多少都與需求蒐集的品質有關,但如果我們不試著從問題的本質出發,思考原本的觀念與作法有何不當之處,那麼不管需求文件寫得多詳細、採用什麼開發工具、什麼軟體平台,恐怕最後都會面臨相同的困境。

為了描述以上的問題,並指出解決問題的方向,《軟體工程與 Microsoft Visual Studio Team System》的作者在書中自創了兩個新名詞:value-up 與 work-down,它們分別代表了不同的軟體開發思維模式 (paradigm)。

Work-down 代表過去的軟體開發思維模式,也就是類似前面舉的例子,先列出要完成的功能清單,然後每當完成了一件工作,就把該工作項目從清單中移除或槓掉。等到工作清單裡面的工作都完成了,就代表專案完成了。我在中文版裡面把 work-down paradigm 譯為「減工思維模式」。

相對於「減工思維模式」,是所謂的 value-up paradigm,我在書中譯為「增值思維模式」,它強調的是持續為專案增加新的客戶價值。什麼是顧客價值?講白一點就是客戶想要的、或對他有用的東西。這些客戶價值當然也是根據事前規劃的工作清單所引導,但專案是否完成並不是以清單裏的工作是否做完來決定,而是看專案是否實現了所有的顧客價值 (customer value)。換句話說,這種思維比較站在使用者的立場,認為開發出來的軟體就應該符合使用者的需求。這也正是極致編程(eXtreme Programming,XP)的精神之一--擁抱改變。

可是這麼一來,如果使用者的需求一直變來變去,恐怕沒有一個團隊撐得下去。因此,有了正確的觀念之後,還要配合適當的方法才行。這當中最重要的關鍵,個人以為是反覆與漸進的開發方式--既然軟體的需求一定會改變,那就不要一次定江山;把軟體需求分成幾個小的階段逐次完成,每完成一小步,還可以視情況調整開發方向,對使用者與開發團隊雙方都有好處。這也符合 XP 的精神--邊開車邊調整方向。

可是,有些類型的專案卻不適合這樣做,例如大型的政府標案,這類型的專案通常在一開始就要決定預算和專案範圍,而且以後也不可能更改預算(從其他預算挪用除外)。因此,除非一開始預算就非常充足,否則當使用者提出比較重大的需求變更時,開發團隊通常得根據合約拒絕使用者增加或變更需求。若預算充足,個人比較一廂情願的想法是,開發團隊不用太在意合約裡面的軟體規格,只要 end-user 滿意,實際上還是可以採用增值思維的模式來開發專案,以確保最終的產品符合使用者的需要,我想這才是最重要的吧。

像政府標案這類的軟體專案,通常需要比較正規的、重量級的開發流程,例如 CMMI。相對的,另一種不那麼正式、允許較多彈性的專案,則適用於輕量級的、可機動調整的開發方法,例如 XP。有了正確的觀念與適當的開發方法,如果少了方便的工具,效果也會大打折扣,甚至無法持續下去。因此,Visual Studio Team System 在設計時就考慮到要支援 XP 與 CMMI 這兩種不同「量級」的專案類型,所以預設就提供了 XP 和 CMMI 的開發流程範本,讓團隊能夠以增值方法來開發這兩種類型的專案(當然也支援其他開發流程,你甚至可以自訂流程範本)。至於實務上的要怎麼做,這是本書的其他章節要談的,這次就先聊到這裡吧!

Visual Studio 2008 練功秘笈全系列

4/17/2008
精誠(恆逸)資訊的講師們推出了 Visual Studio 2008 全系列書,預計 3 月 13 日到 3/14 日上市,對研究新技術有興趣或工作上有需要的朋友可以參考看看。

《微軟解決方案框架精要》簡介與試讀章節下載

4/17/2008
書  名:微軟解決方案框架精要-以 MSF 建構成功的解決方案
作  者:Michael S. V. Turner
翻  譯:蔡煥麟
校閱監修:歐宣修、陳盈學、朱子傑、何美玲
出版日期:2007/3/15

簡介

本書是第一本完整介紹 MSF v4 的書籍,內容涵蓋 MSF 的所有基本原則、思維、紀律、與最佳實務,堪稱 MSF 的權威指南。作者本身也是解決方案交付的專家,他在書中提供了實際的範例和個案研究,協助您將這套靈活、彈性的框架套用在任何專案上,以建構成功的技術解決方案。
專案經理固然能從本書獲得啟發,而其他團隊成員若也能了解 MSF 的基本原則與精神,對於凝聚團隊共識,以及彼此的溝通合作也都會有幫助;方法論專家則可以根據團隊和專案的需要,發展出一套以 MSF 為核心理念的開發流程或方法論。


透過本書,您將學習如何:

  • 制定彈性的解決方案交付生命週期
  • 以漸進的方式來定義、設計、建置、穩定化(stabilize)、以及部署符合商業需求的解決方案
  • 建立一個能夠提升團隊效率的動態團隊模型
  • 管理個人、專案團隊、和組織在交付解決方案方面的就緒程度(readiness)
  • 積極降低專案風險
  • 符合發行準則,並確認解決方案已經達成利害關係人的期望和使用者的需求
  • 在專案的每個階段運用治理活動和檢查點(checkpoints)
下載
另外,我將本書所涵蓋的 MSF v4 相關主題整理成 mindmap (見下圖),希望有助於學習和理解。

關於本書的校閱
像這樣一本內容紮實、又包含許多抽象概念的書籍,在翻譯時程緊迫的情況下,如果沒有人幫忙 review,實在很難想像最後的品質會是如何。本書有多位先進參與 review 工作,雖然彼此未曾謀面,但他們卻義務幫了我很多忙。因此,在這裡要再次謝謝他們的協助。特別是歐兄(歐宣修),我是因為翻譯這本書才與他結識,而從他給我的 review 建議中,可以明顯感受到他所付出的心力。不只是感謝,他的專業與細心也讓我打心底佩服。
最後要聲明的是,雖然有這麼多人協助校閱,但由於匆忙付梓,恐仍有疏漏之處。若中文版的內容有任何瑕疵,都是我的責任。讀者如有任何建議、內容勘誤、甚至讀書心得,都歡迎與我聯繫,或在此部落格留言。
閱讀愉快!
到博客來網路書店購買本書

《軟體工程與 VSTS》介紹與試讀章節下載

4/17/2008
書  名:軟體工程與 Microsoft Visual Studio Team System
作  者:Sam Guckenheimer
翻  譯:蔡煥麟
出版日期:2006/9/20

簡介 (Introduction)

樸實的書名清楚點出了本書的重點所在,就是軟體工程與 Micrsoft Visual Studio Team System(VSTS) 二者。一個是理論構想,一個是輔助工具,作者恰如其分地將兩者結合在這本書裡面。正如 Ivar Jacobson(物件導向三巨頭之一)在本書的序言中所說的,這是一本兼具理論與實務的技術書籍。

本書由碁峰出版,採頁頁對譯的編排方式,並提供中文版的索引。

閱讀環境

您不需要在電腦前面一邊閱讀本書一邊操作(雖然我有時候也會這麼做),因為這不是一本逐步教學的 how-to 書籍;但我想一個舒適安靜的環境是絕對必要的(例如圖書館、臥室 )。書中舉的一些實例可能正好是你目前開發專案時碰到的問題,或者與你過去的開發經驗吻合,因而激發你的靈感,讓你更進一步去思考過去的作法有什麼缺點,以及往後該如何改善。不論是 Hmm...(掩卷沉思)、唉~(仰天長歎)、還是 A-ha! (豁然開朗),在閱讀時,我都很喜歡這種感覺。希望您也能在書中找到對自己有用的東西。

下載試讀章節 (Free Chapters)
相關的讀書心得可以到[閱讀筆記]主題區查閱。
對本書的讚美 (Praise for the Book)
「太吸引人了!這本書詳細說明了 VSTS 有哪些功能,以及為甚麼要把這些功能加入 VSTS——這些寶貴資訊只有微軟內部的員工才有辦法提供。也許更重要的,是作者在介紹每一項功能或如何操作的指示時,都會詳細解釋為什麼這些功能對你這麼重要。本書揚棄了以往開發流程的缺點,並取各家所長,指出方法論的未來發展方向,並點出哪些度量資訊能夠用來改良和客製化你在開發專案時採用的方法論。」
  ——Mark Michaelis,《Essential C# 2.0》的作者
「對任何想要使用 Visual Studio Team System 和微軟解決方案架構(Microsoft Solution Framework,MSF)4.0 版的人來說,這本書絕對非讀不可。本書的一個關鍵主題是『敏捷與責任歸屬』,它解釋了軟體開發方法的思維模式轉移至增值(value-up)方法的過程,並說明 Team System 如何支援增值方法。作者以大量的實用範例來說明如何以 VSTS 實踐增值開發方法,而且每個範例都傳達了某些重要的訊息。」
  ——Aaron Kowall,EDS Applications Portfolio Development, Innovation Engineering
「Sam Guckenheimer在公開透明機制方面的先進理念,將徹底改變我們管理軟體專案的方式。不要光只是把 Visual Studio Team System 買回去;你應該要學習如何充分利用它來改變我們的開發習慣並創造價值。Sam 會告訴你該怎麼做。」
  ——David J. Anderson,《Agile Management for Software Engineering》的作者
「Sam 把 Visual Studio Team System 的精華都放到這 250 頁當中了。如果你的工作與軟體開發有關——不論是開發人員、測試人員、專案經理、架構師、還是資訊長(CIO)——你的團隊都應該要人手一本。本書拉近了現代軟體工程理論與開發實務的距離,並以清晰易懂的範例說明如何利用 Team System 實踐它們。這本書和之前的一些書籍最大的不同點,就是它理論與實務並重。不論你是否已經在使用 VSTS、正在考慮是否採用、或者只是想利用它來提高生產力和輔助企業校準(business alignment),你都能在書中發現許多有用的資訊與見解。這是一本非常有趣、實用、而且容易閱讀的書籍。」
  ——Rick LaPlante,Microsoft Visual Studio Team System 部門總經理
「Sam Guckenheimer 是軟體測試社群公認的專家與良師,很高興看到他終於出書了,而且這本書還清楚闡明了他在軟體工程方面的理念。
  ——Cem Kaner,佛羅里達理工學院,軟體工程教授,法學與哲學博士;《Lessons Learned in Software Testing》與《Testing Computer Software》的主要作者
「在這本書裡面,Sam Guckenheimer 捕捉了 Team System 與增值軟體開發思維模式的完整意涵。此思維模式和以往那種計算工作做完多少的方式截然不同,其核心概念在於測量已交付的客戶價值,Team Systsm 就是依循此理念所設計出來的實作品。你會發現 Team System 為專案提供了前所未有的透明度,此透明度將能大幅改善團隊成員的互動與專案的可預測性。更重要的是,它並未因此而增加團隊成員的負擔和工作時間。閱讀本書將能讓你體會 Team System 的完整設計理念與它所帶來的增值軟體開發良性循環的好處。」
  ——Rob Caron,內容架構師,微軟;《Team System Nexus》的作者
「Sam Guckenheimer 堪稱是技術的外交官。在以機動性見長的敏捷學派游擊隊與 CMMI 正規軍對壘的世界中,Sam 提供了一個讓兩者和平共存的方法。此空前創舉使它成為第一本、也是最重要的一本軟體工程書籍。在討論一些像是規劃、撰寫文件、企業治理、稽核、與組織等焦點議題時,Sam 同時展示了敏捷與正規的實務作法,並且說明採用它們的最佳條件。即使書中的範例主要是以 VSTS 來說明,但其理念與指引卻是放諸四海皆準的。本書是寫給專案的所有角色成員,不論他們在實務上選擇的是重量級還是輕量級的方法,Sam 都提供了實用的建議。本書內容新穎且符合時代潮流,其中還論及服務導向架構、測試驅動開發、以及使用者介面社群所發展出來的一些設計技巧。Sam 的這本書可說是軟體界的超優質著作。」
  ——Bill Curtis 博士,chief process officer,Borland Software Corporation;《People Capability Maturity Model》的主要作者
「Sam Guckenheimer 是真正的使用者代言人。他透過 Team System 向世人展示一個提供流程自動化、以度量資訊輔助管理、與幾乎完全公開透明的軟體開發平台。他展現了一種既實用又容易達成的軟體工程方法,同時,他也並未忽略我們有許多亟需解決的棘手問題。」
  ——James Behling,Accenture Delivery Methods 方法論的主架構師,Accenture
「Sam Guckenheimer 和我總是以同樣的方式來支援程式開發小組與作業小組,Sam 的這本書提供一種容易理解、以流程為中心的方法,實現了 MSF 與 Visual Studio Team Sytem 所倡導的軟體開發最佳實務。『瀑布式模型』業已失敗,但這本書仍可以指引你利用 Visual Studio Team System 與恰好足夠達成任務的流程邁向快速開發的康莊大道。」
  ——Brian White,資深產品經理,iConclude, Inc.,《Software Configuration Management Strategies》與《Rational ClearCase: A Practical Introduction》的作者
「透明化是現代敏捷開發環境的關鍵要素。Sam 一直以來都倡導以工具來協助建立完整與透明的整體架構,好讓它們能同時適用於敏捷專案和大型的團隊。一個彼此信任的環境加上敏捷方法的實踐,將能造就更具生產力的開發團隊。要製作像是專案開發速度這類的統計報告已經是輕而易舉的事。現在,所有團隊成員——包括商業分析師、架構師、與測試人員,都能共同參與敏捷開發流程了。」
  ——Granville “Randy” Miller, 《A Practical Guide to eXtreme Programming》與
《Advanced Use Case Modeling》的共同作者
「你能想像一個供軟體工程使用的企業流程再造(Business Process Re-engineering,BPR)工具嗎?一個真的能夠幫助 IT 產業更加精實的工具?這就是這本書所要談的!它是一道通向軟體工程新世紀的大門,進入此門將令你大開眼界。本書要處理的議題很單純,就是:VSTS 能否將我們的 IT 產業從原本工匠藝術成分佔多數的情況變得更科學一些?Sam Guckenheimer 不僅解釋了為什麼這點非常重要,他還提供許多實用的小秘訣,告訴你如何能在不增加人工負擔的形況下提高開發團隊的生產力與效率。
  ——Francis T. Delgado,資深程式經理,Avanade, Inc.

技術提供:Blogger.