在團隊協作類別中有四項實踐--stakeholder的積極參與,和他人一起建模,公開展示模型,和集體所有制。stakeholder的積極參與對你的成功至關重要,因為你正是為了這些project stakeholder開發系統,正是為了了解和實現他們的需求。換言之,你需要和你的甲方們密切合作,這就自然的想到了和他人一起建模--這個“他人”也包括你的stakeholder。當你的建模工作有多人參加時(至少一個project stakeholder和一個除你之外的開發人員),你就需要和眾人共同協作,相互促進,取長補短。一個擅長于業務過程建模和業務規則定義的敏捷建模者看不到的方面,一個精通結構化建模技術(例如UML類圖或數據模型)的人極有可能看得到。一樣的道理,系統的直接用戶給你的團隊提供的信息極可能是高級經理提供不了的。所以,要有這樣的觀點:你要在項目甲方和開發團隊中營造一種積極參與的氛圍,只有這樣,才能夠收集各種不同的觀點和經驗。集體所有制能夠提升協作性,因為一個人單獨的進行建模的工作,他很快就會遇到瓶頸,而如果每個人都能夠為建模工作獻計獻策,那么你們就能夠成為一個團隊,輕易的解決問題。公開展示模型能夠使得人們對模型“瞻前顧后”變得容易了,能夠立刻考慮模型傳達的信息,從而提高團隊的協作性。當然,我們是假設模型都在眾人的視線之內,或者這些模型都是大家目前正在開發或相關的。這方面的主題我在Organizing an Agile Modeling Room中有詳細的討論。
迭代和遞增類別中包括了使用合適的artifact,并行創建模型,切換到另外的artifact,小增量建模這幾項實踐。不論哪一個artifact,都有它的長處和短處,任何一個單獨的模型都不足以充分的描述你的項目的各個主要方面(如需求、架構)。例如你會發現你為了識別系統的需求,常常需要組合使用用例、業務規則定義、和技術需求定義。單單靠用例就能令project stakeholder立馬告訴你他們所有的使用需求嗎?這恐怕不太可能。你可以試試換用諸如業務規則之類的artifact來捕獲他們的所有業務政策,再換用諸如技術需求的artifact來捕獲他們的非功能需求。否則,他們會想起點什么就告訴你什么,還會返回去討論先前提過的細節,甚至是改變他們的原來的主意。你的需求識別工作通常是一個動態的過程,分析、架構、設計工作也是一樣。 我相信物力論中指出了人們以此種方式思考的原因,我們思考的方式明顯是雜亂的。敏捷建模者要認識到人們是以一種動態的方式在思考,特別是人們處于群體行為時,這樣才能制定對策。敏捷建模者并行創建模型,從而能夠最廣泛的收集信息。這項實踐又是由實踐切換到另外的artifact和小增量建模來支持的--你可能正在使用用例來捕獲使用需求的相關信息,而當stakeholder開始討論他們對編輯屏幕的要求時,你最好是使用基本用戶界面原型或是傳統用戶界面原型來記錄這些需求。你需要在不同的artifact之間來來回回,每一個artifact最好都需要編碼來驗證,這種方式可以由小增量建模的實踐來實現--最典型的方式就是在這個artifact上做一會兒工作,再換一個artifact,依此類推。
簡單這個類別包括了創建簡單的內容,簡單地建模,使用最簡單的工具這幾項核心實踐。創建簡單的內容和簡單地建模這兩個實踐集中于模型的簡單性,在建模過程中這兩項實踐通產是密不可分的。把精力集中在如何簡單描述,建模者常常會發現一些使得你手頭的模型簡單化的方法。舉個例子,我曾經參加了一項存儲層軟件的開發工作,軟件的概念類似于EJB的persistence container,封裝了領域對象的一些存儲操作。結果我們架構和設計非常的復雜,我們試著找到一種辦法:建立一張簡單的圖表,幫助開發人員理解如何使用存儲層來工作。其間我們還發現重構能夠使我們的設計易于理解。實踐使用最簡單的工具能夠使得過程變得簡單。工具越簡單就越容易使用,這就降低了他人在你的模型上工作的門檻,也就增加了實際中別人去這么做的機會,這也包括了你的project stakeholder。通過使用最簡單的工具,簡單描述模型也變得更自然了。此外,當你使用一些簡單/低精度的工具,例如索引卡片,即時貼,白板的時候,你就能親身體驗這些簡單工具的效力,你在不知不覺中已經強化了一些概念:最簡單的解決方法實際上也能非常有效,對你正在開發的系統采用簡單的設計。
驗證類別包含了兩個核心實踐:測試性思維和用代碼驗證。有一條哲學,我常從中受益:“如果你無法測試它,你就不應該建立它,而你建立的一切都應該加以測試?!边@使得我在系統建模時就考慮測試,也使得我積極的去獲取我的模型的反饋--實際上,我把該條哲學歸納為“考慮你創建的所有artifact的可測試性,以及驗證所有種類的artifact?!钡@并不僅僅局限于AM的范圍之內。通過這種可測試性的考慮,在我建模時,我能夠建立起可測試的模型,而且積極的通過編碼來驗證模型,這樣,我就能夠盡快的證實我的模型是真正可以測試的。
輔助實踐
文檔類別包括了三項輔助實踐:丟棄臨時模型,合同模型要正式,非到萬不得已不更新。在項目的進行中,需求、對需求的理解、以及對可能的解決方案的理解,都在不斷變化(回憶一下原則擁抱變化)。為了反映這種變化,你需要同步改進你大部分的項目artifact,包括模型和文檔。就像在敏捷文檔討論的那樣,比較好的方法是,不到萬不得已不要更新你的模型和文檔,這種做法才算是敏捷方法。遵循這項實踐,如果你發現一個模型如果不再需要更新,那就是說這個模型對你的團隊已經沒什么價值了,一個沒有價值的模型就可以視為臨時模型,可以丟棄。不過,要注意合同模型。它定義了你的系統和其他系統之間的接口,不太可能經常改變,因為它們的重要性是勿庸置疑的。一言以蔽之,如果你有個非合同模型不再更新,那就意味著它已經沒有用了。
為溝通建模和為理解建模這兩項實踐屬于動機類別。實際上,這兩項實踐并沒有太多的聯系,有時候你創建模型的目的是為了研究和理解問題,有時候你的目的是為了和其他人交流你的想法,有時候你的目的包括了上述兩者。就像你在圖1中看到的,這兩項實踐常常會一起引出另兩類的實踐,這是下文要討論的主題。
最后,生產率類別中包括使用建模標準,逐漸應用模式,以及重用現有的資源這幾項實踐。重用現有資源這個實踐要求你盡量利用他人的工作成果并從中受益,這有很多種思考方向:一種是應用模式,根據經驗,我認為它是所有重用方法中最有效率的一種,因為你重用的都是其它開發人員久經驗證的解決方案 (Ambler, 1999);另一種是遵循建模標準和指南,實際上,不論是標準還是指南,都能夠提高你工作的一致性。是的,你可以自己寫指南,有時你必須要這么做,因為你的實際環境中會有一些特別的情況。但是你只需要在Internet上稍做搜索就可以找到很多的開發指南。例如,你可javaCodingStandards找到Java的開發指南。
類別間的聯系
讓我們考慮團隊協作類別。簡單類別中的實踐增強了實踐stakeholder的積極參與的效果,因為簡單性消除了參與的代溝。迭代和遞增類別中的實踐也使得參與成為可能,尤其是并行創建模型,因為它增大了stakeholder們參加的機會。動機類別中的實踐可以提高集體所有制和和他人一起建模的效果,對問題的理解和溝通通??梢约ぐl人們的協作精神,簡單類別的實踐也也坑達到激發協作效果,因為它降低了參與的門檻。公開展示模型的效果可以通過生產力類別中的實踐得到提高。遵循標準,應用模式的做法可以增加一致性和可讀性,而重用現有的資源(例如通用架構),則給別人開了一個好頭,使別人能夠在你模型的基礎上繼續。迭代和遞增類的實踐可以支持集體所有制的實行,特別是并行創建模型和切換到另外的artifact,它們使得人們在適當的模型上共同開發。
簡單類別的實踐由另外幾類的實踐來輔助。使用建模標準和逐漸應用模式這兩項實踐支持同一種建模語言(使用標準和容易理解的模式),從而支持了實踐簡單地建模。文檔類別的實踐也可以支持簡單類別的實踐--只有到萬不得已才更新模型,這樣,你才不會給模型增加不必要的信息。才有可能創建簡單的內容以及簡單地建模。
現在再來看迭代和遞增類別。很明顯,團隊協作類別的實踐支持該類的實踐,由于團隊的參與,針對目前的情況選用正確artifact的機會就增大了,你就可以根據需要來切換使用不同的artifact。驗證類實踐能夠賦予你使用遞增方法的勇氣,特別是在你用代碼驗證的時候。保證你想法的易測性,你就更有把握同時操作多個artifact,并在它們之間切換,因為測試問題要求你從多個方面來看待它。文檔類實踐同樣可以促進遞增方法,特別是非到萬不得已不更新。但是合同模型要正式這個實踐抑止了遞增方法的應用,因為你總是希望能夠盡早的建立和其他系統間的接口標準。切換到另外的artifact和丟棄臨時模型之間也能產生正面的效果,因為一個模型完成目的之后就把工作切換到另一個模型上去。簡單類實踐對這個類別也很重要,通過使用最簡單的工具,你在不同的artifact間來回切換就變得更容易了,你節省了熟悉工具的時間,只把精力集中在簡單的內容和描述上,你也可以較容易記住模型要傳達的信息。最后,動機類實踐可以令你同時進行多個建模工作,因為對于復雜的系統,你需要從多個方面去溝通,去理解,因此你需要在適當的artifact間來回切換,這樣才能有效的做到這一點。
驗證類實踐可由簡單類實踐來支持--創建簡單的內容和簡單地建模能使你更容易進行測試性思維。迭代和漸增類實踐也能提高驗證類實踐。例如,在你切換到另外的Artifact時,就可能切換到源代碼,這樣你就可以看到模型確實可以運行。
簡單類實踐可以推進生產力類實踐。當你使用簡單模型工作時,逐漸應用模式就更容易一些;當你簡單地建模時,使用建模標準也會容易一些,而模型的簡單、易懂,也會使你比較容易的重用現有的資源,例如企業需求模型或通用的架構模型。
簡單類實踐以及迭代和漸增類實踐可以支持文檔類實踐的進行。文檔越簡單就越容易使用--如果你的文檔容易理解,這樣你就有把握萬不得已才更新你的文檔,因為你知道做到這一點很簡單;文檔如果很復雜,你的項目風險就很大,因為沒有把握什么時候文檔需要更新。很明顯,非到萬不得已不更新和丟棄臨時模型的運作環境可以其它的實踐來改善,例如切換到另外的artifact、小增量建模。
那,你想成為一個敏捷建模者嗎?
個性通才還是專才?
敏捷建模者的個性
Alistair Cockburn指出:很多的方法學都定義了軟件開發項目中開發人員所擔任的角色,同時還定義個各個角色執行的任務,盡管入席,這些方法并沒有定義這些角色最適合的人選。一個人要想成功的擔任某個角色,他應當很好的適應它--雖然這并不需要人們掌握所有的技能,但人們必須要慢慢的熟悉這些技術。我的經驗告訴我,要成為一個成功的敏捷建模者,下面的列出的個性是必要的:
團隊競賽 第一點,也是最重要的一點,敏捷建模者總是積極的尋求協作,因為他們意識到他們不是萬事通,他們需要不同的觀點,這樣才能做到最好。軟件開發可不是游泳,單干是非常危險的。在敏捷的字典中沒有“我”這個詞。
暢所欲言 敏捷建模者都有良好的溝通技巧--他們能夠表達出他們想法,能夠傾聽,能夠主動獲取反饋,并且能夠把需要的寫出來。
腳踏實地敏捷建模者應當腳踏實地。他們的精力都集中在滿足用戶的需求上,他們不會在模型上畫蛇添足,即便那雙足是多么的好看。他們滿足于提供可能的方案中最簡單的一種,當然,前提是要能夠完成工作。
好奇 敏捷建模者樂衷于研究問題,解決問題。
凡是都問個為什么 敏捷建模者看問題從不會至于表面,而是會打破沙鍋問到底。他們從不會就想當然的認為一個產品或一項技術和它們的廣告上說的那樣,他們會自己試一試。
實事求是 敏捷建模者都非常的謙遜,他們從不認為自己是個萬事通,所以他們會在建立好模型之后,用代碼來小心的證明模型的正確。
勇氣 敏捷建模者應當愿意去計劃一個想法,然后做出模型,再想辦法用代碼來驗證。如果結果不理想,他們就會返工,檢查他們的方法,或是放棄原先的想法。把你的想法告訴你的同伴,再來驗證它的正確,這是需要很大的勇氣的。
根據實驗 敏捷建模者應當愿意嘗試新的方法,例如一項新的(或是已有的)建模技術。一般而言,他們也會接受敏捷建模開發技術,必要時,為了驗證想法,他們愿意同傳統的思想做斗爭,例如在一個項目中減少文檔數量。
有紀律 要堅持不懈的遵循敏捷建模的實踐。對你來說,你可能會在不經意間說,“加上這個功能吧,無傷大雅?!被蚴?,“我比project stakeholder更了解?!痹贏M的道路上要想不偏離方向,是需要一定的紀律性的。
如果你不具有上面列出的所有個性,那該怎么辦呢,你是不是還想成為一個敏捷建模者呢?不用擔心,你只需要少量的努力就能夠勝任。相信我,我也沒有辦法做到100%的腳踏實地和實事求是,我也經常遇到溝通問題。沒有人能夠擁有所有的個性,大部分人都只能擁有一些個性。每個人都有不同點,這些不同點正是敏捷團隊力量的源泉。某些人可能生來就好奇,另一些人的工作積極性可能比較強。人無完人嘛。
通才還是專才?
當你要增加團隊成員時,所要處理的一個至關重要的問題是你希望保持的通才和專才的比率。要回答這個問題,你需要考慮現代軟件開發環境。圖1是企業統一過程(Enterprise Unified Process EUP) 的生命周期。(譯注:原文中并沒有提供這副圖,根據我的猜測,應該就是RUP的概述部分的那張生命周期圖,但是因為沒有取得瑞理公司的授權,所以我暫時也不便引用這張圖,大家可以參閱RUP的相關資料。)圖左邊的EUP的工作流程暗示著軟件開發的復雜--你需要進行業務建模,收集需求,分析和設計系統等等--而這還只是冰山一角。就像圖中列出的那樣,從先啟到產品化的各個階段,預示著在項目的過程中,不同的時間需要你集中于不同的地方,這需要不同的技能。有一個觀點是很明確的,軟件開發非常的復雜,任何一項工作都需要高超的技能和豐富的經驗。首要的,要認識到這種復雜性是軟件開發與身俱來的,而不是EUP使然的,即便你的團隊采用的是XP方法,抑或是DSDM(Stapleton, 1997)方法,或是SCRUM (Beedle & Schwaber, 2001)方法,這種復雜性也還是存在的。盡管這些方法的生命周期看上去并不像EUP那樣的復雜,但它們仍然需要配置管理活動,需要管理活動等等,只是它們處理問題的態度不同而已。
很多的組織對此的第一反應就是建立一個專才的團隊。專才的最基本的含義是指那些特別精通某一項任務的人,因此他們的效率也特別的高。這樣一支團隊,要想高效率的運作,你需要組合這些專才,讓每人負責一塊任務,解決之后就把手頭的工作傳給另一個人。這個概念就類似于“流水線”的想法,如果你是在大量的生產汽車,這種方式會非常的有效,但是以我的經驗,在手工的軟件中采用這種方式并不是太合適。而且,這種方式需要一個大團隊的支持--如果軟件開發中有N中不同的任務,你至少就需要N位專才才能滿足這種方法的要求。但N是多大?20?50?100?這取決于你對專業定義的細節程度,是吧?如果你傾向于每位開發人員只處理一種artifact,那單單處理建模工作,就需要20多位的專才,在modeling artifacts essay列出了各種的artifact。如果你傾向于每位開發人員只負責一種角色,那再一個EUP的項目中也需要11中角色才能完成所有的工作流程。專才通常都很難同人合作,他們缺少謙遜的品質,意識不到其它人的專項技能能夠為他的工作增添價值,他們也意識不到他們的所作所為可能為給后續的工作造成麻煩,也許他們需要返工,也許他們現在的努力會白費。關于專才的另一個問題是,即使是在他們擅長的領域,他們的技能也可能根本就沒有那么精熟。IT產業的技術高變動率,導致了開發人員使用了幾個月的新技術,開始熟悉它,就聲稱自己已經是這方面的專家了,因為和他具有同樣層次經驗的人畢竟不多。要建立一個專才組成的團隊,這也是一個很明顯的問題。
那么,建立一支僅有通才的團隊會怎樣呢?每個人都對軟件開發有不錯的了解,但是都缺乏足夠詳細的必需知識,完成不了工作。項目需要那些對現階段使用的技術和技巧都非常熟悉的人。如果你是在使用Enterprise JavaBeans (EJB),那你既需要對Java編程精通的人,也需要對EJB開發精通的人。一個使用Oracle的團隊,幕后肯定有一位Oracle數據庫管理專家。一個開發經紀人業務軟件的團隊,就需要一位能夠了解股票和債券之間的細微差別的人。
我的經驗是,兩種極端的方式都不可取,你應該取它們的中間點。一種方法是團隊中一部分人是通才,一部分人是專才。通才能夠起到團隊的連接劑的作用,通才注重遠景,專才注重項目的具體的難點。這樣做的好處是通才的長處能夠彌補專才的短處,反之也是一樣,由于這種平衡性,通才和專才組對能夠發揮出極大的優勢。一個更好的方法是團隊中主要是通才,僅有一兩個專才。例如,我認為我應該算是一個通才,我擅長于處理項目中各項技能之間的配合,而且還精通業務應用軟件建模,以及對象存儲和Java編程。我的另一位同事也是位通才,特別擅長建模,EJB開發,以及測試。還有一位堪稱通才的同事則精于網絡通信和Java編程。這樣一支由通才組成,但又有一項或多項特技的團隊,優勢是很明顯的,他們能夠迅速的找到共同點,因為他們畢竟都是通才,而且他們之間有能夠做到優勢互補。它的劣勢在于這種人才一般都比較稀缺,動輒都需花費10年甚至20年的時間才能夠培養出這種通才,因此是很難得到的。如果你的團隊中有一些這種人,那你的運氣真是太好了。 要認識到新手通常一開始都是專才,這很重要。軟件開發的新手面對著需要消化的大量知識,往往不知所措,這很正常。大多數人一開始一開始會把精力集中在開發的一兩個方面,也許是Java編程,也許是獲取用戶需求,然后以這方面的經驗為基礎,再逐漸的拓展知識的覆蓋面。隨著時間的增長,經驗在不斷的累積,他們會慢慢的完善自己的技能樹,他們會軟件開發中各個技能如何配合會更加了解,同時,他們還擅長于一兩門特技。