我工作過(guò)的公司,曾經(jīng)有一個(gè)小伙,他的代碼,縮進(jìn)不是靠Tab,而是“按下空格鍵,任代碼隨意后退”,他的代碼,彎彎曲曲,難看至極。前兩天,他跟我說(shuō)“我筆試得了90多分,當(dāng)場(chǎng)拿到了4.5K的Offer?!笨梢?jiàn),筆試是毫無(wú)意義的測(cè)試手段。
btw:還有問(wèn)題,這樣招人效率不是很高,也比較累,緊急招人的情況不適用。當(dāng)然,緊急招人的項(xiàng)目,通??隙ㄊ歉悴缓玫摹?/div>
posted @
2006-05-30 16:11 讀書(shū)、思考、生活 閱讀(29031) |
評(píng)論 (36) |
編輯 收藏
大多數(shù)程序員,都極度痛恨寫(xiě)文檔。Coding是愉快的,而Write是痛苦的。有一部分原因,其實(shí)是要?dú)w咎于程序員自身,以我的經(jīng)驗(yàn),很多程序員往往會(huì)“艱于表達(dá)”,尤其是用“文字、圖表、PPT、Word”之類(lèi)的Office Document來(lái)表達(dá)。當(dāng)然,還有一部分原因,是由于很多項(xiàng)目開(kāi)發(fā)實(shí)踐中,文檔的前后矛盾、形式主義、反復(fù)修改、歧義重重,常常讓程序員們抓狂。
?
UML是一個(gè)比較好的工具,但是,僅僅靠UML,是無(wú)法將項(xiàng)目的知識(shí)描述清楚的。也有不少項(xiàng)目組在引入了UML之后發(fā)現(xiàn),文檔的工作量不但沒(méi)有減少,而是更多了。隨著項(xiàng)目的進(jìn)展,需要維護(hù)的設(shè)計(jì)文檔數(shù)量,也更多了。也因此造成了更多的前后矛盾,形式主義,反復(fù)修改。
?
根本的痛苦,并不在于一開(kāi)始寫(xiě)一份文檔,而在于所有寫(xiě)下的文檔,都必須跟隨項(xiàng)目的進(jìn)展而隨之變化。當(dāng)我們寫(xiě)出來(lái)的文檔越多,需要被持續(xù)維護(hù)的文檔也就越多,需要反復(fù)檢查文檔間的可能存在的矛盾也就越多,所有扔出去的石頭,最后都會(huì)落回到自己頭上。
?
于是,還有不少項(xiàng)目組,將文檔工作與代碼工作截然分開(kāi),文檔就寫(xiě)一次,用來(lái)應(yīng)付上面的管理層,而代碼自管自的繼續(xù)開(kāi)發(fā)。對(duì)于小型項(xiàng)目來(lái)說(shuō),這其實(shí)是一個(gè)不錯(cuò)的權(quán)宜之計(jì)。但是一旦項(xiàng)目越來(lái)越龐大、復(fù)雜。所有的隱性的知識(shí),都僅僅存在于程序員的腦子里,所有成文的東西,都可能是錯(cuò)的,而真實(shí)的情況,卻隱藏在代碼之中。如果代碼質(zhì)量再糟糕一些,后來(lái)維護(hù)的朋友,就遭遇火坑了。
?
文檔,寫(xiě)還是不寫(xiě),這是一個(gè)問(wèn)題!
?
還記得測(cè)試驅(qū)動(dòng)開(kāi)發(fā)嗎?為自己的每一個(gè)方法,每一個(gè)類(lèi),都寫(xiě)出單元測(cè)試來(lái)。不但如此,更加徹底的做法是,在寫(xiě)代碼之前,先寫(xiě)測(cè)試用例。這樣才能保證不會(huì)忘記寫(xiě)測(cè)試用例。更大的好處在于,這樣有助于思考、有助于獲得更加完善的設(shè)計(jì),有助于寫(xiě)出更加高質(zhì)量的代碼,有助于安全的重構(gòu),有助于自動(dòng)化的持續(xù)集成實(shí)踐??傊?,是好得不能再好的一項(xiàng)開(kāi)發(fā)實(shí)踐。
?
這一實(shí)踐之所以可行,就在于他將繁雜的集中的測(cè)試工作,分解為日常的,必須不斷進(jìn)行的工作。當(dāng)你每天都在寫(xiě)測(cè)試用例,當(dāng)你的每一個(gè)測(cè)試用例,都能夠與代碼完全對(duì)應(yīng)時(shí),壓力反而減輕了,工作量也更少了,更重要的,一些優(yōu)良的習(xí)慣也因此被養(yǎng)成了。
?
在兩年前,我要開(kāi)始一個(gè)全新的P2P網(wǎng)絡(luò)電視項(xiàng)目時(shí),也在考慮關(guān)于文檔的問(wèn)題。當(dāng)時(shí)我發(fā)現(xiàn)了Open Source的WikiPedia。這是一個(gè)PHP的WIKI,最大的應(yīng)用是維基百科全書(shū)。因此,這個(gè)項(xiàng)目的質(zhì)量就絕對(duì)值得信賴。我就將它拿過(guò)來(lái),作為我們項(xiàng)目文檔管理的工具。
?
用Wiki來(lái)管理項(xiàng)目文檔,基于以下一些考慮:
文檔是項(xiàng)目的知識(shí),這些知識(shí)必須集中管理、容易獲取、人人可以編輯。
項(xiàng)目在生長(zhǎng),代碼在增加,文檔也必須能夠跟隨項(xiàng)目自然生長(zhǎng),強(qiáng)行劃分設(shè)計(jì)階段和開(kāi)發(fā)階段,是不可取的。
Wiki不是傳統(tǒng)的項(xiàng)目文檔,而是一個(gè)應(yīng)交流需要,可能隨時(shí)增刪改的知識(shí)庫(kù)。項(xiàng)目組的成員,遇到問(wèn)題,就應(yīng)該首先查看Wiki,如果這是Wiki中沒(méi)有,那么他應(yīng)該找人詢問(wèn)。而那個(gè)知道答案的人,如果他不想再今后不斷的回答同一問(wèn)題,就應(yīng)該把這個(gè)答案寫(xiě)入Wiki,這就是Wiki條目增長(zhǎng)的自然動(dòng)力。
傳統(tǒng)文檔最大的問(wèn)題在于浪費(fèi),而Wiki通過(guò)持續(xù)修改,按需提供的方式,保證了所有寫(xiě)下的文字,一定有超過(guò)一個(gè)人需要讀它。
?
在Wikipedia的基礎(chǔ)上,我又做了一些增強(qiáng),以更好的輔助項(xiàng)目的管理。
Include功能,增加include標(biāo)簽,可以在一個(gè)條目中,引入其他條目的全文,而不是僅僅增加一個(gè)link。
文檔的層次結(jié)構(gòu),當(dāng)項(xiàng)目的文檔條目逐漸增加,分門(mén)別類(lèi)的條目,更加便于查找,也可以有效的避免條目重名的問(wèn)題。
一個(gè)Click,就能夠創(chuàng)建新一個(gè)條目,用于填寫(xiě)當(dāng)天的工作安排。
相應(yīng)的管理制度,也必須建立起來(lái)。
每日15分鐘文檔制度,基于“填寫(xiě)當(dāng)日工作”的功能,我規(guī)定每個(gè)項(xiàng)目組成員,每天要花三個(gè)5分鐘來(lái)寫(xiě)文檔,早上的5分鐘,填寫(xiě)當(dāng)日工作計(jì)劃。中午的5分鐘填寫(xiě)上午的工作情況,下班前的5分鐘,填寫(xiě)下午的工作情況。這樣,每天的文檔工作相當(dāng)輕松,但是文檔能夠保證持續(xù)的跟隨項(xiàng)目成長(zhǎng)下去。更進(jìn)一步的,這樣的制度,對(duì)于項(xiàng)目的進(jìn)度控制,也很有幫助。
User Case條目驅(qū)動(dòng),所有分解出去的User Case,在分配到責(zé)任人之后,該責(zé)任人的第一項(xiàng)工作,就是在Wiki中寫(xiě)下對(duì)于這個(gè)User Case的理解。隨后項(xiàng)目進(jìn)展,也應(yīng)該持續(xù)的維護(hù)這個(gè)條目。
同時(shí)進(jìn)行Bug的管理,Bug也作為Wiki中的條目,以便于和其他條目項(xiàng)目引用。
每次Check In CVS時(shí),必須寫(xiě)注釋。這是更加細(xì)節(jié)的文檔,然后我還做了一個(gè)小程序,能夠自動(dòng)的從CVSTrac中讀出當(dāng)天Check In代碼的注釋。供每個(gè)人在寫(xiě)當(dāng)天文檔的時(shí)候引用。
總而言之,我對(duì)于項(xiàng)目文檔的看法,并不是非此即彼的極端主義者。在我看來(lái),好的項(xiàng)目文檔管理政策,應(yīng)該有助于集中團(tuán)隊(duì)知識(shí)和智慧,同時(shí)不要讓程序員痛苦和反感。這樣才叫做有效的項(xiàng)目管理。仿造Martin Fowler的著名文獻(xiàn)《持續(xù)集成》,我給這篇Blog起這樣一個(gè)名字《軟件開(kāi)發(fā)文檔的持續(xù)集成》,希望能夠引發(fā)更多的、更深入的思考。
posted @
2006-05-12 14:23 讀書(shū)、思考、生活 閱讀(28648) |
評(píng)論 (3) |
編輯 收藏
我新到這家公司,就開(kāi)始了一場(chǎng)死亡之旅,我們的項(xiàng)目開(kāi)發(fā)周期是3個(gè)月,人員大概有3~6個(gè)不一定。而以我的經(jīng)驗(yàn),我們大概要做的,是一個(gè)3~5個(gè)人年的非常復(fù)雜的創(chuàng)新型項(xiàng)目。新加盟的技術(shù)總監(jiān),是一個(gè)崇尚文檔交流的“老干部”,因此,我們花了一個(gè)月的時(shí)間,在寫(xiě)各種各樣的設(shè)計(jì)文檔。真正能夠用于開(kāi)發(fā)的時(shí)間,是2個(gè)月。
?
我們這個(gè)小組的另外一位組員,也是一位經(jīng)驗(yàn)豐富的項(xiàng)目經(jīng)理,他崇尚的,是文檔UML化描述。因此,我現(xiàn)在除了寫(xiě)文檔,還要用Rational Rose畫(huà)好多好多的圖~~~
?
在他們兩位來(lái)這個(gè)項(xiàng)目組之前,我其實(shí)已經(jīng)寫(xiě)出了一份基本完整的User Case列表,而且和另外一位組員已經(jīng)進(jìn)入測(cè)試驅(qū)動(dòng)的、結(jié)對(duì)編程階段了。。。
?
?
大家可能已經(jīng)看出來(lái)了,這其中的開(kāi)發(fā)模式,簡(jiǎn)直就是混亂不堪。到底是文檔驅(qū)動(dòng)?UML驅(qū)動(dòng)?用例驅(qū)動(dòng)?還是測(cè)試驅(qū)動(dòng)呢?
?
問(wèn)題還不止這些,我們的大老板比較喜歡和我們一起討論設(shè)計(jì),甚至?xí)臀覀儬?zhēng)論具體的某個(gè)算法。開(kāi)發(fā)文檔沒(méi)有統(tǒng)一的管理,匯報(bào)機(jī)制沒(méi)有明確的定義,項(xiàng)目需求隨時(shí)都可能變動(dòng),就連到底我們這個(gè)小組會(huì)有幾個(gè)人,都還是一個(gè)未知數(shù),這樣的死亡之組,不知各位有什么好的建議?
?背景資料介紹完畢,抱怨結(jié)束,下面討論正題:
文檔驅(qū)動(dòng)、測(cè)試驅(qū)動(dòng)、用例驅(qū)動(dòng)、模型驅(qū)動(dòng)、特征驅(qū)動(dòng)。。。。他們都要解決的是什么問(wèn)題?
要回答這個(gè)問(wèn)題,還真不容易。我們得問(wèn)一個(gè)更加重要的問(wèn)題,真正驅(qū)動(dòng)項(xiàng)目的,究竟是什么呢?我想,應(yīng)該是需求吧?
?
那么,這些“文檔”、“測(cè)試”、“用例”、“模型”、“特征”,究竟是什么呢?對(duì)于需求的描述!我們之所以不會(huì)直接用需求來(lái)驅(qū)動(dòng)項(xiàng)目開(kāi)發(fā),而是要借助工具,來(lái)幫助我們描述需求,就是因?yàn)榭谡Z(yǔ)化的需求描述是非常模糊的,充滿歧義的。所以,選擇什么來(lái)驅(qū)動(dòng)我們的項(xiàng)目,其實(shí)就是要看,以上這些工具,哪一個(gè)能夠更好、更準(zhǔn)確的描述需求?
?
文檔其實(shí)是最難準(zhǔn)確描述需求的一種方式,如果是純文字的文檔,就更難。我們的技術(shù)總監(jiān),非常喜歡讀寫(xiě)文檔,我最近也創(chuàng)下了一天寫(xiě)47頁(yè)文檔的最新記錄。但是,當(dāng)我們開(kāi)會(huì)的時(shí)候,我還是經(jīng)常需要提醒我們的技術(shù)總監(jiān),麻煩他再仔細(xì)看看文檔第XX頁(yè)的第XX段,以及配合著另一份文檔的XX小節(jié),來(lái)確切的理解我的意思!如果沒(méi)有我的解釋,他就會(huì)誤解我的文檔。
?
當(dāng)然,如果要寫(xiě)出不需要我來(lái)解釋,他就能理解的文檔,那么文檔的工作量,將會(huì)極其驚人!我以前寫(xiě)過(guò)一篇blog,《Jacobson博士演講觀后感》是我對(duì)UP的創(chuàng)始人的極度反感的集中體現(xiàn)。GHawk,以及交大林老師的所謂“UP”的觀點(diǎn),當(dāng)然不可能獲得我的贊同。在GHawk的最新一篇blog:《UP & XP之爭(zhēng),意義何在?(續(xù))》中,GHawk說(shuō):“唯一的問(wèn)題是:“如何確保測(cè)試用例的質(zhì)量”。顯然,我們不能把一把不直的尺子度量出來(lái)的結(jié)果作為可靠的參考依據(jù)。怎么解決呢?“結(jié)對(duì)編程”么?嗯,這是一個(gè)不錯(cuò)的方式,那么最終該信賴誰(shuí)呢?是Pair中的A還是B呢?或者,是Leader么?那么又是誰(shuí)提出的要求呢?是老板么?還是客戶?政府?法規(guī)?市場(chǎng)?……問(wèn)題沒(méi)有終結(jié)了。”
?
由此我可以推斷,他對(duì)于XP的認(rèn)識(shí),基本上是停留在猜測(cè)的階段。對(duì)于這篇blog的觀點(diǎn),我就不逐一反駁了,我的猜測(cè)是,他經(jīng)歷過(guò)一次失敗的XP嘗試,而究其原因,我猜測(cè)是因?yàn)樗麄兡莻€(gè)所謂的XP Team中,沒(méi)有一個(gè)人,曾經(jīng)實(shí)踐過(guò)一次正規(guī)的XP開(kāi)發(fā)。
?
再來(lái)看模型驅(qū)動(dòng),這中間有一個(gè)大問(wèn)題,因?yàn)樾枨笫恰皢?wèn)題域”的范疇,而模型,則是“解答域”的范疇,試圖通過(guò)解答域的精確描述,來(lái)實(shí)現(xiàn)對(duì)于需求的準(zhǔn)確描述,肯定不靠譜啊。
?
特征驅(qū)動(dòng),我認(rèn)為FDD其實(shí)是老方法的新名詞,具體的實(shí)踐,可能更加接近測(cè)試、迭代式的過(guò)程。了解不過(guò),所以我也不打算多說(shuō)。
?
用例驅(qū)動(dòng)與測(cè)試驅(qū)動(dòng),其實(shí)我認(rèn)為這是一個(gè)硬幣的兩面,用例要盡快的翻譯為測(cè)試用例,而測(cè)試用例,正是為了更加準(zhǔn)確的表述需求用例。這是我能夠想到的,驅(qū)動(dòng)項(xiàng)目開(kāi)發(fā)的,最好的方法!
posted @
2006-04-26 00:32 讀書(shū)、思考、生活 閱讀(29568) |
評(píng)論 (31) |
編輯 收藏
幾段在腦子里盤(pán)旋了很久的話:
?
帶一個(gè)項(xiàng)目,要保證項(xiàng)目的質(zhì)量,當(dāng)然要靠Team Leader的水平。那么,什么才是最重要的項(xiàng)目質(zhì)量呢?當(dāng)然是代碼質(zhì)量!一個(gè)軟件項(xiàng)目,最重要的產(chǎn)品當(dāng)然是代碼!
?
如果這個(gè)Leader看不懂項(xiàng)目的代碼,他只能通過(guò)要求文檔的質(zhì)量,來(lái)間接的控制代碼的質(zhì)量。一個(gè)能夠看得懂代碼的Leader,他就能夠直接控制代碼質(zhì)量。而能夠直接控制代碼質(zhì)量的Leader,對(duì)于文檔的要求,會(huì)合理很多。
?
直接控制與間接控制,哪一個(gè)更加有效,是不言而喻的。當(dāng)然,那些沒(méi)有代碼閱讀能力的Leader,他們會(huì)更加強(qiáng)調(diào)文檔的重要性,甚至舍本逐末,認(rèn)為文檔質(zhì)量才是項(xiàng)目質(zhì)量的體現(xiàn)。進(jìn)而變態(tài)地追求文檔完美,以至于浪費(fèi)了程序員寫(xiě)代碼的時(shí)間。這樣的Leader,根本就不可能管好項(xiàng)目的。
?
公司往往會(huì)出于恐慌,向員工要求很多詳盡的文檔,主要是為了防止員工離職帶來(lái)的損失。而問(wèn)題在于,公司的主要努力,應(yīng)該用于留住員工,而不是用于加強(qiáng)“善后能力”。更不是為了增強(qiáng)善后能力,搞得員工越發(fā)想離開(kāi)這家公司。
?
btw:
?
補(bǔ)記一段交鋒對(duì)話:
?
UP和Agile都是工程過(guò)程實(shí)踐的總結(jié),林德彰先生說(shuō)過(guò)“UP是正楷,XP是草書(shū)。先學(xué)好了UP,才能學(xué)好XP;先學(xué)XP再學(xué)UP就會(huì)亂套?!?
Agile強(qiáng)調(diào)的是“代碼是真正有價(jià)值的東西?!边@同樣也是實(shí)踐的結(jié)果。二位對(duì)于過(guò)程有不同的看法并不能說(shuō)明孰是孰非,這只是在不同的實(shí)踐內(nèi)容和階段上的總結(jié)。在過(guò)程的選用問(wèn)題上,只有不斷地實(shí)踐才是前進(jìn)的方向。?
?
?
我的回答是:
?
林德彰的說(shuō)法,是一個(gè)在校教師,典型的和稀泥的說(shuō)法,我不同意。
?
沒(méi)想到今天有一個(gè)朋友WANG回了一帖:
?
老林是在校教師?你應(yīng)該去看一下人家在美國(guó)打拼的經(jīng)驗(yàn)~~??
?
我的回復(fù)是:
他在美國(guó)打拼怎么了?還有好多土生土長(zhǎng)的美國(guó)人,也不鳥(niǎo)那什么UP呢?
我為什么要聽(tīng)一個(gè)海龜來(lái)上課呢?
這年頭,海龜還不夠多嗎?
另外對(duì)GHawk多說(shuō)一句話:讓組員快速磨合的最好辦法,是結(jié)對(duì)編程,而不是大家埋頭寫(xiě)文檔。
posted @
2006-04-22 21:35 讀書(shū)、思考、生活 閱讀(29985) |
評(píng)論 (21) |
編輯 收藏