每個(gè)軟件項(xiàng)目都是在號(hào)角和樂(lè)觀中開(kāi)始的。即使是在深夜中拼湊起來(lái)的最微不足道的小項(xiàng)目,也都是源于一個(gè)星光璀璨的夢(mèng)想。團(tuán)隊(duì)相信,只要幾行代碼和一些開(kāi)源庫(kù),我們就可以完成任務(wù),并可以為我們優(yōu)雅、完美的工作而接受獎(jiǎng)勵(lì)。
但是在幾周或幾個(gè)月后,我們就會(huì)從夢(mèng)中醒來(lái),并發(fā)現(xiàn)git存儲(chǔ)庫(kù)中充滿了各種決策、修訂和恢復(fù)。它足夠好了嗎?滿足標(biāo)準(zhǔn)了嗎?會(huì)有人真正使用它嗎?很多時(shí)候,軟件團(tuán)隊(duì)深入到一個(gè)項(xiàng)目中,卻發(fā)現(xiàn)這些問(wèn)題的答案中至少有部分是否定的。有沒(méi)有辦法預(yù)見(jiàn)到它的到來(lái)呢?
的確,有時(shí)候,即使是最好的編程計(jì)劃在沒(méi)有任何警告的情況下也會(huì)誤入歧途,但大多數(shù)情況下,一個(gè)注定要失敗的結(jié)局對(duì)于任何一個(gè)一路上密切關(guān)注它的人來(lái)說(shuō)都是顯而易見(jiàn)的。
下面是軟件工程師列出的十幾個(gè)軟件項(xiàng)目可能失敗的早期警告信號(hào)。
在管理層支持下的轉(zhuǎn)變
這個(gè)項(xiàng)目的業(yè)務(wù)冠軍是在某天早上試圖把他或她的孩子送進(jìn)南加州大學(xué)或耶魯大學(xué)后被捕的嗎?CIO是否取消了最近的三次進(jìn)度評(píng)審會(huì)議?算一下,你是否已經(jīng)大概有一年沒(méi)見(jiàn)到CIO了?財(cái)務(wù)總監(jiān)問(wèn)過(guò)你的員工預(yù)算嗎?合并能掃除一半的組織結(jié)構(gòu)圖么?
許多軟件項(xiàng)目失敗的原因可能與編寫(xiě)代碼的人沒(méi)有任何關(guān)系。如果管理層中有人喜歡您的軟件項(xiàng)目,就會(huì)通過(guò)審批流程以支持它,如果這個(gè)人消失了,支持也就會(huì)消失。你的愿景其實(shí)是無(wú)關(guān)緊要的。如果另一個(gè)團(tuán)隊(duì)對(duì)公司的發(fā)展方向有不同的看法,并且這個(gè)派別控制了公司,你的項(xiàng)目就可能會(huì)消失。所以,盡管你可能不想這么做,但還是要關(guān)注政治。
市場(chǎng)的變化
重要的不僅僅是內(nèi)部支持。消費(fèi)者和他們所驅(qū)動(dòng)的市場(chǎng)也能改變他們的欲望。軟件項(xiàng)目需要幾個(gè)月的時(shí)間才能完成,而市場(chǎng)卻可能在幾周、幾天甚至幾分鐘內(nèi)就消失了。
如果你的項(xiàng)目針對(duì)的是一個(gè)快速發(fā)展的市場(chǎng),那么當(dāng)你完成代碼時(shí),市場(chǎng)變得完全不同的可能性就會(huì)更高。即使你的項(xiàng)目是在一個(gè)更穩(wěn)定的領(lǐng)域,新的競(jìng)爭(zhēng)也幾乎可以在一夜之間出現(xiàn)。如果你的團(tuán)隊(duì)沒(méi)有一個(gè)計(jì)劃來(lái)適應(yīng)不斷變化的趨勢(shì),就很有可能會(huì)被淘汰。
程序員的跳槽
人們總是在換工作,優(yōu)秀的程序員需求量總是很大,但是如果團(tuán)隊(duì)不斷地流失人員,那么就會(huì)出現(xiàn)問(wèn)題。如果工資已經(jīng)足夠高,工作條件已經(jīng)足夠好,那么項(xiàng)目本身就可能是罪魁禍?zhǔn)?。也許編碼人員被需求弄糊涂了,他們跳起來(lái)是為了避免心理壓力。也許整個(gè)架構(gòu)都是錯(cuò)的,他們已經(jīng)無(wú)法讓它正常工作。也許團(tuán)隊(duì)中有一些害群之馬正在趕走所有人。團(tuán)隊(duì)外流是一個(gè)預(yù)兆,表明有些事情是錯(cuò)誤的,可能會(huì)破壞項(xiàng)目成功的機(jī)會(huì)。
在簡(jiǎn)單的事情上花了太多時(shí)間
團(tuán)隊(duì)對(duì)簡(jiǎn)單的變更響應(yīng)速度有多快?他們能改變背景顏色嗎?將復(fù)選框移動(dòng)幾個(gè)像素?如果微小的更改需求沒(méi)有得到快速處理,那么大的更改將會(huì)需要更長(zhǎng)時(shí)間。
有時(shí)候糟糕的架構(gòu)決策會(huì)讓一些簡(jiǎn)單的事情變得幾乎不可能。我的一個(gè)工作項(xiàng)目要求我在數(shù)據(jù)庫(kù)中填寫(xiě)一個(gè)額外的列,這需要更改五個(gè)不同的微服務(wù)。這意味著要檢查五個(gè)不同的項(xiàng)目,通過(guò)五個(gè)不同的代碼審查,并編寫(xiě)五組不同的單元測(cè)試。它們都只是為了更新一行中的一個(gè)數(shù)字。
開(kāi)發(fā)人員有一種過(guò)度復(fù)雜化簡(jiǎn)單任務(wù)的習(xí)慣,有時(shí)最聰明的開(kāi)發(fā)人員反而是最糟糕的。有些更改將是困難的,但是如果團(tuán)隊(duì)在處理大多數(shù)小更改時(shí)也遇到困難,那么這就表明基礎(chǔ)過(guò)于復(fù)雜了。
沒(méi)有成本模型
估計(jì)每個(gè)用戶的成本比以往任何時(shí)候都要容易。云計(jì)算按小時(shí)計(jì)算,無(wú)服務(wù)器系統(tǒng)按事務(wù)定價(jià)。如果用戶每個(gè)月使用M字節(jié)的數(shù)據(jù)訪問(wèn)服務(wù)器N次,你知道對(duì)這些數(shù)據(jù)進(jìn)行所有計(jì)算需要多少成本嗎?
一些項(xiàng)目團(tuán)隊(duì)對(duì)成本一無(wú)所知,然后他們可能會(huì)發(fā)現(xiàn),一筆花費(fèi)X便士的交易只能帶來(lái)Y便士的收入,遺憾的是,X > Y。該軟件可以編譯和運(yùn)行,也沒(méi)有太多bug,但是項(xiàng)目失敗了,因?yàn)樗且慌_(tái)賠錢(qián)的機(jī)器。跟蹤成本和確定一個(gè)明確的目標(biāo)是至關(guān)重要的,否則開(kāi)發(fā)人員可能最終構(gòu)建出一個(gè)非常酷的東西,但需要周圍有6臺(tái)最復(fù)雜的云機(jī)器。
開(kāi)發(fā)人員一味地遵從一個(gè)天才
有聰明人在你的項(xiàng)目上工作是件好事。但是當(dāng)一個(gè)人的思想占據(jù)主導(dǎo)地位時(shí),危險(xiǎn)就來(lái)了。除了一些奇怪的情況外,如果每個(gè)人都說(shuō)“我們?nèi)?wèn)X吧”,而X總是同一個(gè)名字,這通常就是一個(gè)不好的信號(hào)。如果X死了或者跑到山里去尋找啟示,這個(gè)項(xiàng)目就會(huì)失去方向。
但是,如果X不離開(kāi),情況可能會(huì)更糟,因?yàn)槊總€(gè)人都希望由X來(lái)執(zhí)行決策,而出現(xiàn)的瓶頸會(huì)阻止所有人繼續(xù)前進(jìn)。X可能享受權(quán)力,X也可能是一個(gè)合格的天才,但強(qiáng)迫所有的工作都得到X的批準(zhǔn)將是緩慢的。
代碼標(biāo)準(zhǔn)主導(dǎo)著討論
美學(xué)很重要,但一些開(kāi)發(fā)人員過(guò)分關(guān)注代碼中的空白空間,并將這一點(diǎn)發(fā)揮到了極致。所謂的代碼標(biāo)準(zhǔn)只是妨礙團(tuán)隊(duì)成員行使權(quán)力的一種方式。在代碼評(píng)審期間,當(dāng)他們發(fā)現(xiàn)一個(gè)放錯(cuò)位置的空格或制表符時(shí),他們就不祥地宣布“沒(méi)有達(dá)到標(biāo)準(zhǔn)”。
功能最終決定著一個(gè)項(xiàng)目的成敗,如果團(tuán)隊(duì)不停止?fàn)幷撏獠咳藛T永遠(yuǎn)不會(huì)看到的內(nèi)部代碼的美學(xué),那么團(tuán)隊(duì)可能永遠(yuǎn)也無(wú)法達(dá)到目標(biāo)。
指標(biāo)看起來(lái)太過(guò)完美
通過(guò)指標(biāo)來(lái)衡量團(tuán)隊(duì)進(jìn)度是一個(gè)必要的要求,但是對(duì)它們過(guò)于信任也是很危險(xiǎn)的,因?yàn)殚_(kāi)發(fā)人員會(huì)玩弄您所能想象的任何度量。一位朋友解釋說(shuō),他的老板有一個(gè)指標(biāo),可以衡量有注釋的功能的比例,所以他使用了著名的AI聊天機(jī)器人Eliza,以確保他的所有功能都有注釋,無(wú)論是多么愚蠢的注釋。他甚至編寫(xiě)了一些快速代碼來(lái)搜索變量名稱,并將它們包括在毫無(wú)意義的注釋當(dāng)中。他的統(tǒng)計(jì)數(shù)據(jù)非常棒。要求所有功能都有注釋的老板從來(lái)沒(méi)有讀過(guò)這些注釋,所以老板也一直不知道內(nèi)情。他剛剛在儀表板上看到了100%的注釋代碼,然后就去了高爾夫球場(chǎng)。
目光朝著閃亮的新事物移去
新的語(yǔ)言、庫(kù)和體系結(jié)構(gòu)都很棒,但它們也有自己的定位,而且通常不在關(guān)鍵任務(wù)的堆棧中。它們適用于示范和探索性的次要項(xiàng)目。對(duì)于項(xiàng)目外圍的非必要微服務(wù)來(lái)說(shuō),它們是可以的。如果團(tuán)隊(duì)有一個(gè)舒適的時(shí)間表,并且也沒(méi)有其他選擇,那么這些選擇可能是可以接受的。
然而,隱藏在對(duì)某些新軟件解決方案的渴望中的真正含義是,開(kāi)發(fā)人員可能正在與當(dāng)前的項(xiàng)目或體系結(jié)構(gòu)作斗爭(zhēng)。當(dāng)前的計(jì)劃可能已經(jīng)產(chǎn)生了太多的小故障、錯(cuò)誤和令人頭疼的事。他們可能正試圖迫使一些方形圖庫(kù)與圓形API進(jìn)行通信。膠水代碼可能比實(shí)際代碼還要來(lái)的多。對(duì)當(dāng)前方法的不滿可能導(dǎo)致開(kāi)發(fā)人員在不斷地徘徊。
業(yè)務(wù)規(guī)范的不明確
這個(gè)過(guò)程的前景是否模糊得令人難以置信?它是否充斥著像“disrupt”或“meta”這樣的流行詞,而不是像“HTTP”或“AJAX”這樣的技術(shù)術(shù)語(yǔ)?是否存在大量關(guān)于“改變世界”的討論,卻很少討論數(shù)據(jù)庫(kù)的選擇或架構(gòu)策略?
創(chuàng)建軟件需要具體的技術(shù)決策,而有時(shí)候那些項(xiàng)目的幻想家并沒(méi)有花足夠的時(shí)間來(lái)考慮如何實(shí)現(xiàn)這個(gè)目標(biāo)。有時(shí)候,他們很幸運(yùn),因?yàn)橛幸恍┞斆鞯娜四軌驑?gòu)建它,但是通常情況下,不清晰的業(yè)務(wù)規(guī)范通常會(huì)導(dǎo)致項(xiàng)目的失敗。也許它需要太多的帶寬。也許延遲會(huì)讓用戶界面變得遲鈍。也許所有這些云計(jì)算的成本還不足以被廣告和訂閱費(fèi)所覆蓋。我們不知道會(huì)發(fā)生什么,因?yàn)橐?guī)劃文件里沒(méi)有涉及到那個(gè)細(xì)節(jié)。
不受控制的復(fù)雜性
管理軟件項(xiàng)目的主要任務(wù)是找到一種方法來(lái)讓用戶滿意,同時(shí)將任務(wù)的復(fù)雜性降低到可管理的程度。每個(gè)人都希望代碼能夠輕松地閱讀他們的想法并提供答案,但是這些東西只有在用戶都想要相同的東西時(shí)才有可能。
當(dāng)多個(gè)派系開(kāi)始要求不同的東西時(shí),項(xiàng)目就開(kāi)始出錯(cuò)了。如果他們對(duì)項(xiàng)目擁有太多的權(quán)力,而項(xiàng)目經(jīng)理不能找到一種方法來(lái)協(xié)調(diào)他們的興趣并讓每個(gè)人都滿意時(shí),那么項(xiàng)目將變得非常復(fù)雜,完成它所需的代碼量將會(huì)大幅增加。如果項(xiàng)目團(tuán)隊(duì)不能有效地說(shuō)“不”,那么工作的復(fù)雜性將比程序員編寫(xiě)代碼的速度增長(zhǎng)得快得多。
糟糕的測(cè)試計(jì)劃
有些程序員喜歡大量編寫(xiě)新代碼。每一行都是一個(gè)真實(shí)的創(chuàng)作,一個(gè)關(guān)于比特的藝術(shù)陳述,將被轉(zhuǎn)換成其他的一些比特集合。從前黑暗的地方,現(xiàn)在有了光明。這是一種美妙的感覺(jué),但這只是其中的一部分。僅僅構(gòu)建軟件是不夠的,我們需要了解它何時(shí)可以正確運(yùn)行,這樣我們才能夠了解它何時(shí)會(huì)失敗。
一個(gè)好的測(cè)試計(jì)劃應(yīng)該向后看,而不是向前看,檢查是否一切正常。這并不是能夠憑空變出來(lái)的能夠讓人覺(jué)得興奮和刺激的東西。它只是充滿了嘮叨和提醒,敦促你回去把事情做好。測(cè)試通常并不是愉快的。
但是測(cè)試和構(gòu)建代碼一樣是一門(mén)藝術(shù)。有太多需要進(jìn)行測(cè)試的東西了,你永遠(yuǎn)不可能結(jié)束它。但如果太少,代碼就可能無(wú)法正常工作。如果一個(gè)軟件項(xiàng)目團(tuán)隊(duì)不能平衡創(chuàng)造的喜悅和測(cè)試的繁重工作,他們將走向失敗。
不合理的期望
有些事情對(duì)軟件的使用者來(lái)說(shuō)太容易了,以至于運(yùn)行項(xiàng)目的人常常沒(méi)有意識(shí)到讓這種神奇的功能發(fā)揮作用有多難。許多項(xiàng)目都可以編譯并運(yùn)行,幾乎沒(méi)有錯(cuò)誤,但是如果它們不能滿足用戶的需求,就會(huì)被視為失敗。有時(shí)候問(wèn)題不在于代碼,而在于使用它的人無(wú)法實(shí)現(xiàn)的夢(mèng)想。什么?新的數(shù)據(jù)庫(kù)也不能治療我的禿頂嗎?我還以為它能像《星際迷航》那樣傳送并瞬間移動(dòng)呢!
軟件開(kāi)發(fā)人員需要保持對(duì)項(xiàng)目的控制,以確保大膽的夢(mèng)想家或大思想家無(wú)法指揮項(xiàng)目。如果期望得到合理的控制,項(xiàng)目就有機(jī)會(huì)實(shí)現(xiàn)它們。如果不是,那么,即使是最出色、無(wú)缺陷、低延遲、最先進(jìn)的應(yīng)用程序也可能會(huì)讓人失望。