請(qǐng)您在閱讀本文之前,先了解《高效程序員的45個(gè)習(xí)慣》-之二。
每一期都會(huì)涉及15個(gè)話題,用3期來列出這45個(gè)習(xí)慣,每次不貪多,貪精,大家如果有空,一定要細(xì)細(xì)品味這15個(gè)習(xí)慣。
注意:每一個(gè)好的習(xí)慣,開頭都會(huì)相應(yīng)有一個(gè)唱反調(diào)的句子哦。
16 使用演示獲得頻繁反饋
“客戶不停的更改需求,導(dǎo)致我們嚴(yán)重地延期。他們一次就應(yīng)該想清楚所有想要的東西,然后把這些需求給我們。”
需求就像是流動(dòng)著的油墨。你無法凍結(jié)需求,就像你無法凍結(jié)市場(chǎng)、競(jìng)爭(zhēng)、知識(shí)、進(jìn)化或者成長(zhǎng)一樣。就算你真的凍結(jié)了,也很可能是凍結(jié)了錯(cuò)的東西。
不一致的術(shù)語(yǔ)是導(dǎo)致需求誤解的一個(gè)主要原因。所以,需要維護(hù)一份項(xiàng)目術(shù)語(yǔ)表。人們應(yīng)該可以公開訪問它,一般是在wiki或內(nèi)部網(wǎng)里。
項(xiàng)目啟動(dòng)了一段時(shí)間以后,你就應(yīng)該進(jìn)入一種舒適的狀態(tài),團(tuán)隊(duì)和客戶建立了一種健康的富有創(chuàng)造性的關(guān)系。
17 使用短迭代,增量發(fā)布
“我們?yōu)楹竺娴?年制定了漂亮的項(xiàng)目計(jì)劃,列出了所有的任務(wù)和可交付的時(shí)間表。只要我們那時(shí)候發(fā)布了產(chǎn)品,就可以占領(lǐng)市場(chǎng)”
給我一份詳細(xì)的長(zhǎng)期報(bào)告,我就會(huì)給你一個(gè)注定完蛋的項(xiàng)目。
對(duì)于大項(xiàng)目,最理想的辦法就是小步前進(jìn),這也是敏捷方法的核心。大步跳躍大大地增加了風(fēng)險(xiǎn),小步前進(jìn)才可以幫助你很好地把握平衡。
18 固定的價(jià)格就意味著背叛承諾
“對(duì)這個(gè)項(xiàng)目,我們必須要有固定的報(bào)價(jià)。雖然我們還不清楚項(xiàng)目的具體情況,但仍要有一個(gè)報(bào)價(jià)?!?/font>
固定價(jià)格的合同會(huì)是敏捷團(tuán)隊(duì)的一大難題。我們一直在談?wù)撊绾斡贸掷m(xù)、迭代和增量的方式工作。但是現(xiàn)在卻有些人跑過來,想提早知道它會(huì)花費(fèi)多少時(shí)間及多少成本。
軟件項(xiàng)目天生就是變化無常的,不可重復(fù)。如果要提前給出一個(gè)固定的價(jià)格,就幾乎肯定不能遵守開發(fā)上的承諾。
如果你現(xiàn)在別無選擇,你不得不提供一個(gè)固定價(jià)格,那么你需要學(xué)到真正好的評(píng)估技巧。
19 守護(hù)天使
“你不必為單元測(cè)試花費(fèi)那么多時(shí)間和精力。它只會(huì)拖延項(xiàng)目的進(jìn)度。好歹,你也是一個(gè)不錯(cuò)的程序員—單元測(cè)試只會(huì)浪費(fèi)時(shí)間。”
單元測(cè)試能及時(shí)提供反饋
單元測(cè)試讓你的代碼更加健壯
單元測(cè)試時(shí)有用的設(shè)計(jì)工具
單元測(cè)試是你自信的后臺(tái)
單元測(cè)試是可信的文檔
單元測(cè)試是學(xué)習(xí)工具
20 先用它再實(shí)現(xiàn)它
“前進(jìn),先完成所有的庫(kù)代碼。后面會(huì)有大量時(shí)間看用戶是如何思考的?,F(xiàn)在只要把代碼扔過墻就可以了,我保證它沒有問題。”
很多成功的公司都是靠著“吃自己的狗食”活著。也就是說,如果要讓你的產(chǎn)品盡可能地好,自己先要積極地使用它。
編程之前,先寫測(cè)試。
先寫測(cè)試,你就會(huì)站在代碼用戶的角度來思考,而不僅僅是一個(gè)單純的實(shí)現(xiàn)者,這樣做是有很大區(qū)別的,你會(huì)發(fā)現(xiàn)因?yàn)槟阕约阂褂盟鼈?,所以能設(shè)計(jì)一個(gè)更有用、更一致的接口。
21 不同環(huán)境,就有不同問題
“只要代碼能在你的機(jī)器上運(yùn)行就可以了,誰(shuí)會(huì)去關(guān)心它是否可以在其他平臺(tái)上工作,你又不用其他平臺(tái)?!?/font>
一位同事的代碼失敗了,最終找到了罪魁禍?zhǔn)祝阂粋€(gè).NET環(huán)境下的API在Windows XP和Windows2003上的行為不同。平臺(tái)不同,造成了結(jié)果的不一樣。
使用持久集成工具,在每一種支持的平臺(tái)和環(huán)境中運(yùn)行單元測(cè)試,要積極地尋找問題,而不是等問題來找你。
22 自動(dòng)驗(yàn)收測(cè)試
“很好,你現(xiàn)在用單元測(cè)試來驗(yàn)證代碼是否完成了你期望的行為。發(fā)給客戶吧。我們很快會(huì)知道這是否是用戶期望的功能。”
關(guān)鍵業(yè)務(wù)邏輯必須要獨(dú)立進(jìn)行嚴(yán)格的測(cè)試,并且最后需要通過用戶的審批。但是,你又不可能拉著用戶,逐一模塊確認(rèn)。所以你需要能自動(dòng)比較用戶期望和實(shí)際完成的工作。
FIT(fit.c2.com),即集成測(cè)試框架,它很實(shí)用,可以更容易的使用HTML表格定義測(cè)試用例,并比較測(cè)試結(jié)果數(shù)據(jù)。
23 度量真正的進(jìn)度
“用自己的時(shí)間表報(bào)告工作進(jìn)度。我們會(huì)用它做項(xiàng)目計(jì)劃。不用管那些實(shí)際的工作時(shí)間,每周填滿40小時(shí)就可以了?!?/font>
時(shí)間表很難真實(shí)地反映工作完成狀況,因此它不可以用來進(jìn)行計(jì)劃、評(píng)估或表現(xiàn)評(píng)估。
你曾經(jīng)聽到開發(fā)人員報(bào)告一個(gè)任務(wù)完成了80%么?然而過了一天又一天,一周又一周,那個(gè)任務(wù)仍然是完成80%。
隨意用一個(gè)比率進(jìn)行度量是沒有意義的。所以不應(yīng)該去計(jì)算工作量完成的百分比,而應(yīng)該測(cè)定還剩下多少工作量沒有完成。如果你最初估計(jì)這個(gè)任務(wù)需要40個(gè)小時(shí),在開發(fā)了35個(gè)小時(shí)之后,你認(rèn)為還需要另外30個(gè)小時(shí)的工作。那就得到了很重要的度量結(jié)果(這里誠(chéng)實(shí)非常重要,隱瞞真相毫無意義)
關(guān)注功能,而不是日程表。
24 傾聽用戶的聲音
“用戶就是會(huì)抱怨。這不是你的過錯(cuò),是用戶太愚蠢了,連使用手冊(cè)都看不懂。它不是一個(gè)bug,只是用戶不明白如何使用而已。他們本應(yīng)該知道更多?!?/font>
不管它是否是產(chǎn)品的bug,還是文檔的bug,或者是對(duì)用戶社區(qū)理解的bug,它都是團(tuán)隊(duì)的問題,而不是用戶的問題。
對(duì)于一些軟件,倒霉的用戶必須要配置那些包含了一些魔術(shù)數(shù)字的模糊系統(tǒng)文件,否則系統(tǒng)根本不會(huì)運(yùn)行。系統(tǒng)既沒有錯(cuò)誤提示消息,也不會(huì)崩潰,只是顯示大黑屏和一個(gè)斗大的“退出”按鈕。
每一個(gè)抱怨的背后都隱藏著一個(gè)事實(shí)。找出真相,修復(fù)真正的問題。
沒有愚蠢的用戶;只有愚蠢自大的開發(fā)人員。
“它就是這樣的。”這不是一個(gè)好答案。
你的用戶有可能會(huì)閱讀所有的文檔,記住其中的所有內(nèi)容。但也可能不會(huì)。
25 代碼要清晰地表達(dá)意圖
“可以工作而且易于理解的代碼當(dāng)然好,但是讓人覺得聰明更加重要。別人給你錢是因?yàn)槟隳X子好使,讓我們看看你到底有多聰明?!?/font>
Hoare說“設(shè)計(jì)軟件有兩種方式。一種是設(shè)計(jì)得盡量簡(jiǎn)單,并且明顯沒有缺陷。另一種方式是設(shè)計(jì)得盡量復(fù)雜,并且沒有明顯的缺陷?!?/font>
(Hoare創(chuàng)造了Algol 60編程語(yǔ)言,并發(fā)明了快速排序算法。于1980年獲得圖靈獎(jiǎng)。)
代碼閱讀的次數(shù)要遠(yuǎn)遠(yuǎn)超過編寫的次數(shù),所以在編寫的時(shí)候值得花點(diǎn)功夫讓它讀起來更加簡(jiǎn)單。
當(dāng)開發(fā)人員們像一群旁觀者見到UFO一樣圍在代碼四周,感到恐懼、困惑與無助時(shí),這個(gè)代碼的質(zhì)量就可想而知了。
看一個(gè)例子:
coffeeShop.PlaceOrder(2);//通過閱讀代碼,可以大致明白這是要在咖啡店中下一個(gè)訂單。但是2代表什么意思?
coffeeShop.PlaceOrder(2 /* large cup */); //不妨添加一些注釋。但注釋有時(shí)候是為了幫寫得不好的代碼補(bǔ)漏。
public enum CoffeeCupSize
{
Small,
Medium,
Large
}
coffeeShop.PlaceOrder(CoffeeCupSize,Large);//如果使用上枚舉值,代碼就一目了然了。
應(yīng)該讓自己或團(tuán)隊(duì)的其他任何人,可以讀懂自己一年前寫的代碼,而且只讀一遍就知道它的運(yùn)行機(jī)制。
26 用代碼溝通
“精確地解釋代碼做了什么,每行代碼都要加注釋。不用管為什么要這樣編碼,只要告訴我們做了什么就好了。”
源代碼可以讀懂,不是因?yàn)槠渲械淖⑨專鴳?yīng)該是由于它本身優(yōu)雅而清晰。
要盡量避免使用神秘的變量名。(i常用于循環(huán)索引變量,str常用于表示字符串。如果用str表示循環(huán)索引變量,可真不是好主意)
在代碼可以明確傳遞意圖的地方,不要使用注釋。
解釋代碼做了什么的注釋用處不那么大。相反,注釋要說明為什么會(huì)這樣寫代碼。
27 動(dòng)態(tài)評(píng)估取舍
“性能、生產(chǎn)力、優(yōu)雅、成本以及上市時(shí)間,在軟件開發(fā)過程中都是至關(guān)重要的因素。每一項(xiàng)都必須達(dá)到最理想的狀態(tài)。”
與其花費(fèi)時(shí)間去提升千分之一的性能表現(xiàn),也許減少開發(fā)投入,降低成本,并盡快讓應(yīng)用程序上市銷售更有價(jià)值。
如果現(xiàn)在投入額外的資源和精力,是為了將來可能得到的好處,要確認(rèn)投入一定要得到回報(bào)。(大部分情況下,是不會(huì)有回報(bào)的)
28 增量式編程
“真正的程序員寫起代碼來,一干就是幾個(gè)小時(shí),根本不停,甚至連頭都不抬。不要停下來去編譯你的代碼,只要一直往下寫就好了!”
如果不對(duì)自己編寫的代碼進(jìn)行測(cè)試,保證沒有問題,就不要聯(lián)系幾個(gè)小時(shí),甚至連續(xù)幾分鐘進(jìn)行編程。相反,應(yīng)該采用增量式的編程方式。
采用增量式編程和測(cè)試,會(huì)傾向于創(chuàng)建更小的方法和更具內(nèi)聚性的類。你應(yīng)該經(jīng)常評(píng)估代碼質(zhì)量,并不時(shí)的進(jìn)行許多小調(diào)整,而不是一次修改許多東西。
在寫了幾行代碼之后,你會(huì)迫切地希望進(jìn)行一次構(gòu)建/測(cè)試。在沒有得到反饋時(shí),你不要走的太遠(yuǎn)。
29 保持簡(jiǎn)單
“通過編寫史上最復(fù)雜的程序,你將會(huì)得到美譽(yù)和認(rèn)可,更不用提保住你的工作了?!?/font>
Andy曾經(jīng)認(rèn)識(shí)一個(gè)家伙,他對(duì)設(shè)計(jì)模式非常著迷,想把它們?nèi)加闷饋?。有一次,要寫一個(gè)大概幾百行的代碼程序。在被別人發(fā)現(xiàn)之前,他已經(jīng)成功將17種設(shè)計(jì)模式,都運(yùn)用到那可憐的程序中了?!@不應(yīng)該是編寫敏捷代碼的方式。
問題在于,許多開發(fā)人員傾向于將投入的努力與程序復(fù)雜性混同起來。如果你看到別人給出的解決方案,并評(píng)價(jià)說“非常簡(jiǎn)單且易于理解”,很有可能你會(huì)讓設(shè)計(jì)者不高興。許多開發(fā)人員以自己程序的復(fù)雜性為榮,如果能聽到“Wow,這很難,一定是花了很多時(shí)間和精力才做出來的吧?!?這時(shí),他們就會(huì)面帶自豪的微笑了。其實(shí)應(yīng)當(dāng)恰恰相反,開發(fā)人員更應(yīng)該為自己能夠創(chuàng)建出一個(gè)簡(jiǎn)單并且可用的設(shè)計(jì)而驕傲。
簡(jiǎn)單不是簡(jiǎn)陋。
30 編寫內(nèi)聚的代碼
“你要編寫一些新的代碼,看看IDE中現(xiàn)在打開的是哪個(gè)類,就直接加進(jìn)去吧。如果所有的代碼都在一個(gè)類或組件里面,要找起來是很方便的?!?/font>
內(nèi)聚性用來評(píng)估一個(gè)組建(包、模塊或配件)中成員的功能相關(guān)性。內(nèi)聚程度高,表明各個(gè)成員共同完成了一個(gè)功能特性或是一組功能特性。內(nèi)聚程度低的話,表明各個(gè)成員提供的功能是互不相干的。
類也要遵循內(nèi)聚性。如果一個(gè)類的方法和屬性共同完成了一個(gè)功能,這個(gè)類就是內(nèi)聚的。
不過,不要把一些東西分成很多微小的部分,而使其失去了實(shí)用價(jià)值。當(dāng)你需要一只襪子的時(shí)候,一盒棉線不能帶給你任何幫助。
聯(lián)系客服