每一個(gè)軟件項(xiàng)目都是從遠(yuǎn)大的夢想和宏偉的愿景開始的。或許在另一個(gè)世界的某個(gè)地方,的確會(huì)有一個(gè)項(xiàng)目可以實(shí)現(xiàn)每一個(gè)人的夢想,但是在我們的世界中,軟件項(xiàng)目總是跌跌撞撞地走向終點(diǎn)線,有時(shí)甚至?xí)竭^它。 當(dāng)然,根據(jù)定義,軟件項(xiàng)目的失敗并不總是非此即彼的事情。你可能會(huì)得到運(yùn)行良好但沒人使用的代碼。或者你可能會(huì)得到不能編譯的代碼。有時(shí)你可以從燃燒的殘骸中搶救出一些有用的東西,但最好在它爆炸前逃跑。 當(dāng)悶熱的爛攤子冷卻下來,分析就開始了,因?yàn)槿藗兿胫朗鞘裁吹胤匠隽藛栴}。以下是最常見的罪魁禍?zhǔn)住?/span> 1. 過少的團(tuán)隊(duì)成員 用太少的程序員做太多的事情是一個(gè)常見的問題。開發(fā)人員在耗盡精力之前只能編寫這么多的代碼。我曾經(jīng)在一個(gè)團(tuán)隊(duì)工作過,在這個(gè)團(tuán)隊(duì)中,經(jīng)理認(rèn)為從敏捷團(tuán)隊(duì)中擠出更多工作的正確方法是安排每個(gè)“sprint”,讓它在前一個(gè)sprint之后就立即開始。沒有深思熟慮的停頓來找出什么是有效的,什么是無效的。Sprint 42于周三下午1:59結(jié)束,Sprint 43就于周三下午2:00開始了?;仡櫺苑治鰰?huì)議通常被安排在下一個(gè)sprint開始之后。一些聰明的家伙建議他們將其改名為“馬拉松”,但很快就投入了另一份工作。 當(dāng)然,很難知道究竟有多少程序員才是足夠的。有時(shí)路障和問題會(huì)阻礙我們前進(jìn)。工作量翻倍也許不是經(jīng)理的錯(cuò),但如果你沒有足夠的人手,你的項(xiàng)目就注定要失敗。 2. 團(tuán)隊(duì)成員太多 如果太少的程序員可能是不好的,那么太多就可能會(huì)更糟,因?yàn)榫W(wǎng)絡(luò)效應(yīng)也可能會(huì)毀滅一個(gè)軟件項(xiàng)目。更多的人意味著需要更多的協(xié)調(diào),也就意味著更多的會(huì)議,它將占用原本編寫代碼的時(shí)間。但是如果你召開的會(huì)議不夠多,你很快就會(huì)發(fā)現(xiàn)團(tuán)隊(duì)A的API不能與團(tuán)隊(duì)B的微服務(wù)進(jìn)行銜接。 如果我們可以通過給項(xiàng)目配備過多的人員來砸錢解決問題,那當(dāng)然很好,但你不能這樣做。 3. 太多的溝通 編寫軟件是一門孤獨(dú)的藝術(shù)。人類可以一起工作,但只能在有限的時(shí)間內(nèi)。許多開發(fā)人員討厭開會(huì),因?yàn)樗麄冃枰獙⒆约旱乃季S從沉浸式的邏輯思維轉(zhuǎn)向更開放、更社會(huì)化的模式。這需要時(shí)間。一些團(tuán)隊(duì)領(lǐng)導(dǎo)試圖通過召開更多的會(huì)議來使每個(gè)人保持同步以對(duì)抗失敗。這是一個(gè)崇高的努力,但你依舊可以聽到齒輪的磨擦聲。團(tuán)隊(duì)需要分享足夠的信息來保持同步,但太多的信息只會(huì)浪費(fèi)大腦周期。 4. 基本功能的變化 理論上,開發(fā)人員喜歡認(rèn)為自己是敏捷的。這就是他們擁抱這個(gè)詞的原因。但有時(shí)敏捷會(huì)讓人失去平衡。這一切取決于這種轉(zhuǎn)變是否需要對(duì)基礎(chǔ)框架進(jìn)行根本性的改變。當(dāng)只是移動(dòng)按鈕或改變顏色時(shí),很容易變得敏捷。但是,當(dāng)涉及到需要重新編寫數(shù)據(jù)庫模式或處理分片和復(fù)制時(shí),就沒有一種簡單的方法可以優(yōu)雅地進(jìn)行調(diào)整了。 5. 為工作選擇了錯(cuò)誤的技術(shù) 即使你仔細(xì)計(jì)劃并制定了正確的特性列表,如果使用了錯(cuò)誤的技術(shù),事情也可能會(huì)失敗。例如,數(shù)據(jù)庫被設(shè)計(jì)為通用和靈活的,但是存在架構(gòu)上的限制。推動(dòng)他們?nèi)プ鲆恍┧麄儾幌胱龅氖虑?,?dāng)他們被要求擴(kuò)展時(shí),他們就會(huì)放慢速度,甚至是停止?;蛘?,你可能會(huì)開始使用NoSQL數(shù)據(jù)庫,因?yàn)樗鼈兟犉饋砗芸?,但后來發(fā)現(xiàn)你確實(shí)需要ACID級(jí)別的事務(wù)來保持一致性,而數(shù)據(jù)庫卻不提供這些事務(wù)。 6. 缺乏優(yōu)先級(jí) 好的規(guī)劃者會(huì)列出一個(gè)特性列表,并對(duì)它們進(jìn)行優(yōu)先排序。但有時(shí)優(yōu)先事項(xiàng)與實(shí)施它們的現(xiàn)實(shí)并不一致。在最糟糕的情況下,可能最重要的特性是最難創(chuàng)建的。 你的開發(fā)者該怎么做?如果他們專注于最重要的特性,他們將無法取得任何進(jìn)展,并且可能最終無法交付任何功能。但是如果他們開始完成那些簡單的特性,他們就可能會(huì)得到一些毫無價(jià)值的東西。 好的計(jì)劃所需要的不僅僅是一張清單。對(duì)遠(yuǎn)景的架構(gòu)必須考慮到需求和交付它們的成本。 7. 市場窗口的關(guān)閉 有時(shí)候這不是程序員的錯(cuò)。我曾經(jīng)的一個(gè)項(xiàng)目是把一本最暢銷的參考書變成一個(gè)應(yīng)用程序。在互聯(lián)網(wǎng)出現(xiàn)之前的幾年里,這本書非常暢銷。該公司計(jì)劃利用這一需求,制作一個(gè)交互式的版本,讓人們可以對(duì)數(shù)據(jù)進(jìn)行排序和搜索。編程團(tuán)隊(duì)交付的軟件包含了書中的所有內(nèi)容,但比書本身更快、更漂亮、更輕。但是沒有人想要它了。因?yàn)橐呀?jīng)有足夠多的其他來源了,沒有人需要另一個(gè)應(yīng)用程序來做幾乎和新聞網(wǎng)站一樣的事情。 有時(shí)候一個(gè)想法看起來很不錯(cuò),但市場已經(jīng)改變了。 8. 糟糕的架構(gòu)決策 在一個(gè)項(xiàng)目中,我的任務(wù)是更改數(shù)據(jù)庫中某一行中的一個(gè)數(shù)字。當(dāng)用戶完成注冊(cè)后,我要將用戶的id號(hào)添加到最新的訂單中。聽起來很簡單,對(duì)吧?但是系統(tǒng)是建立在微服務(wù)架構(gòu)上的,我不能通過編寫一行代碼來告訴數(shù)據(jù)庫更新該列來解決這個(gè)問題。不行。架構(gòu)的計(jì)劃是在現(xiàn)有堆棧中添加一個(gè)新的微服務(wù)調(diào)用,即使這樣做也很困難,因?yàn)槲业牡谝粋€(gè)微服務(wù)調(diào)用需要觸發(fā)另一個(gè)微服務(wù)調(diào)用等等。 最后,創(chuàng)建這個(gè)微服務(wù)網(wǎng)絡(luò)的架構(gòu)奇才告訴我,這一切都非常簡單,并勾勒出了一條貫穿整個(gè)體系結(jié)構(gòu)五層的蜿蜒路徑。我的工作是向5個(gè)不同的微服務(wù)添加5個(gè)新的API調(diào)用,這也意味著需要為每個(gè)層添加5組自動(dòng)化測試。這些年來,每個(gè)API都是由不同的團(tuán)隊(duì)開發(fā)的,這就要求我理解和模仿五種不同的編碼風(fēng)格。所有的一切就是為了改變一個(gè)數(shù)字。 架構(gòu)決策可能會(huì)持續(xù)一生--尤其是當(dāng)你的自我意識(shí)已經(jīng)完全投入其中而你無法改變它的時(shí)候。項(xiàng)目經(jīng)理必須時(shí)刻注意主架構(gòu)何時(shí)會(huì)不起作用,并做出重大決策。 9. 政治沖突 將技術(shù)故障歸咎于政治因素似乎有些含糊其辭,但事實(shí)已經(jīng)越來越真實(shí)了。隨著項(xiàng)目的擴(kuò)大和跨越多個(gè)組織,出現(xiàn)派系和團(tuán)隊(duì)來爭奪控制權(quán)、資源和最終權(quán)力也就不足為奇了。 政治派系不同于真正的技術(shù)差異。通常有一些技術(shù)標(biāo)準(zhǔn)或代碼庫會(huì)以不同的方式做同樣的事情。以XML和JSON為例。我能感覺到這兩種技術(shù)的粉絲都急于解釋為什么它們不一樣,以及為什么他們最喜歡的選擇是正確的。但是當(dāng)一個(gè)團(tuán)隊(duì)的一部分喜歡一個(gè)選擇,而另一部分則最尊重有競爭關(guān)系的另一方時(shí),摩擦就會(huì)把他們分開。 隨著架構(gòu)師將應(yīng)用程序拆分為多個(gè)更小的服務(wù)和API,這種情況將變得更加常見。不同的團(tuán)體最終會(huì)控制這些,但他們不會(huì)總是和睦相處。如果A組喜歡JSON,而B組喜歡XML,那么你的團(tuán)隊(duì)要么需要同時(shí)實(shí)現(xiàn)它們,要么更改其中一個(gè)。所有這三種情況,對(duì)于必須同時(shí)與A組和B組合作的團(tuán)隊(duì)來說都是一種痛苦。 10. 押注于還沒有準(zhǔn)備好投入生產(chǎn)的技術(shù) 程序員喜歡最新的工具和框架。他們?cè)敢庀嘈?,新方法將掃除上一代人遺留下來的所有糟粕。 但通常情況下,下一代的技術(shù)可能還沒有準(zhǔn)備好投入生產(chǎn)。新功能或許看起來很完美,但通常會(huì)有一些不太明顯的缺陷。有時(shí)代碼只支持少數(shù)的文件類型,或者只支持幾個(gè)數(shù)據(jù)庫的接口。他們向你保證,其他產(chǎn)品很快就會(huì)推出,但是你的項(xiàng)目需要在這個(gè)月就發(fā)布,而“很快”則可能意味著需要6個(gè)月或更多的時(shí)間才能完成所需的特性。 11. 押注于即將過時(shí)的技術(shù) 根據(jù)我的經(jīng)驗(yàn),舊的技術(shù)通常更可靠,更經(jīng)得起考驗(yàn),但這并不意味著舊技術(shù)是完美的。即使軟件項(xiàng)目已經(jīng)投入使用,也可能會(huì)缺少對(duì)軟件項(xiàng)目至關(guān)重要的特性。更糟糕的是,押注于老技術(shù)可能會(huì)讓你錯(cuò)過未來可能出現(xiàn)的變化。新的思想、協(xié)議和文件格式出現(xiàn)了,但它們可能還無法實(shí)現(xiàn)。如果競爭團(tuán)隊(duì)的某個(gè)人堅(jiān)持認(rèn)為你應(yīng)該支持某種新協(xié)議,那么舊的技術(shù)將會(huì)帶來傷害。 12. 不切實(shí)際的截止日期 截止日期是棘手的。許多項(xiàng)目需要在特定的季節(jié)或事件之前進(jìn)入市場。然而,當(dāng)?shù)谝淮螌懴陆刂谷掌跁r(shí),開發(fā)人員可能還沒有發(fā)現(xiàn)他們前進(jìn)道路上的障礙。然后,如果項(xiàng)目失敗,并且沒有啟動(dòng)軟件,事件就過去了,那么整個(gè)項(xiàng)目就會(huì)被視為失敗,即使代碼已經(jīng)準(zhǔn)備好順利運(yùn)行。截止日期可以幫助每個(gè)人集中精力,齊心協(xié)力,但也可能會(huì)讓人產(chǎn)生不切實(shí)際的期望。 13. 無法預(yù)見的競爭 一個(gè)好的產(chǎn)品經(jīng)理在進(jìn)入市場之前會(huì)調(diào)查競爭情況,但是沒有人能預(yù)測什么樣的競爭會(huì)突然出現(xiàn)。如果新的競爭對(duì)手引入了你必須復(fù)制的新特性,請(qǐng)參閱上面關(guān)于特性更改和優(yōu)先級(jí)不匹配的部分。 14. 匆忙的流程 許多軟件項(xiàng)目都是從想要修復(fù)某些東西的個(gè)人或團(tuán)隊(duì)的愿景開始的。他們可能會(huì)想出“Snapchat for Y”或“Uber for Y”這樣的短語,然后就期望產(chǎn)品團(tuán)隊(duì)能像Snapchat或Uber一樣反應(yīng)迅速。問題在于,確定項(xiàng)目的范圍、描繪數(shù)據(jù)流和設(shè)想U(xiǎn)I的工作量通常是編寫代碼的十倍。而幻想家們想要馬上將想法變成代碼。 線框圖、數(shù)據(jù)庫模式和用戶描述不是一蹴而就的,而是工作中必不可少的一部分。但大多數(shù)人認(rèn)為軟件項(xiàng)目只是編寫代碼來實(shí)現(xiàn)一個(gè)想法而已。 15. 錯(cuò)誤地相信軟件的力量 夢想家常常對(duì)軟件改變世界的力量抱有不切實(shí)際的信念。很多人以為社交媒體會(huì)把我們團(tuán)結(jié)在一起,但不知為何,它只是暴露了一直以來都很明顯的斷層線。軟件項(xiàng)目通常是以幻燈片開始的,這些幻燈片承諾將徹底改變世界的某個(gè)角落。然后,當(dāng)向數(shù)據(jù)庫中塞入數(shù)據(jù)并不能改變?nèi)魏稳藭r(shí),人們就會(huì)感到憤怒、無聊、困惑甚至更糟。他們說,這個(gè)軟件被破壞了,因?yàn)樗茨軐?shí)現(xiàn)大家所期待的神奇轉(zhuǎn)變。 許多軟件項(xiàng)目可以編譯、通過QA、發(fā)布,甚至獲得不錯(cuò)的評(píng)審,但卻最終未能實(shí)現(xiàn)幻燈片上的任何承諾,因?yàn)槟切└淖兪澜绲某兄Z是不可能的。 16. 邪惡的分包商 我們喜歡那些提供庫和工具的廠商,這些庫和工具使得我們只需要使用幾行代碼就能創(chuàng)造奇跡。但是偶爾,他們會(huì)聽到自己的力量,并利用它來摧毀一個(gè)項(xiàng)目。版本1.0的預(yù)算表非常好,以至于管理層會(huì)毫不猶豫地批準(zhǔn)版本2.0。然后供應(yīng)商就可能會(huì)通過三倍或五倍的價(jià)格來擠壓我們。 即使供應(yīng)商不是故意這樣做的,也可以感受到這種影響。免費(fèi)的庫可以讓一個(gè)項(xiàng)目看起來非常便宜。然后,當(dāng)需求飆升,第二個(gè)版本擴(kuò)大了需求時(shí),實(shí)際價(jià)格就會(huì)開始上升了。 17. 翻天覆地的巨變 在大流行和抗議的一年里,沒有什么比時(shí)代精神改變得更快了。該項(xiàng)目是否將強(qiáng)大的隱私保護(hù)作為了一個(gè)核心特征?唉。大流行使得每個(gè)人都對(duì)追蹤接觸者感興趣了。有人想專注于商務(wù)旅行嗎?唉。酒店業(yè)已經(jīng)崩潰了。需要一年或更長時(shí)間的大型軟件項(xiàng)目可能有被災(zāi)難性事件中斷的風(fēng)險(xiǎn)。一開始看起來似乎是個(gè)很不錯(cuò)的想法,但到了要付諸實(shí)踐的時(shí)候,就可能會(huì)變得毫無希望、毫無意義。 18. 技術(shù)遷移 不僅僅是世界的變化??萍冀绲某绷髯兓矔?huì)產(chǎn)生同樣的效果。NoSQL曾經(jīng)是一個(gè)天才的想法,它能夠?qū)⑽覀儚年P(guān)系模式中解放出來。然后又有人意識(shí)到文件的膨脹是因?yàn)槊總€(gè)記錄都帶有一個(gè)本地模式。雖然一個(gè)好的敏捷開發(fā)團(tuán)隊(duì)可以在技術(shù)的巨大變化改變領(lǐng)導(dǎo)層和客戶的態(tài)度時(shí)進(jìn)行調(diào)整。但是即使是最敏捷的團(tuán)隊(duì)也不能處理那些會(huì)把他們的架構(gòu)計(jì)劃全部搞垮的重大變化。這個(gè)系統(tǒng)是建立在假設(shè)X是一個(gè)好主意的前提下的,而在突然之間X變成了一個(gè)垃圾。或許有時(shí)候最好的選擇是把它炸掉,然后再重新開始。 19. 太多附庸 一些軟件項(xiàng)目的起步很好,甚至被成功地發(fā)布了。然后就會(huì)有人添加了一到三個(gè)額外的特性,將新代碼移植到現(xiàn)有的版本上,使代碼繼續(xù)蹣跚前行。英勇的開發(fā)人員可能會(huì)多次實(shí)現(xiàn)這個(gè)目標(biāo),特別是在最初的架構(gòu)師計(jì)劃良好的情況下。但是在某個(gè)時(shí)候,基礎(chǔ)就崩潰了??赡苁菙?shù)據(jù)庫無法處理負(fù)載??赡苁切枰噙B接來滿足各種查詢。好的軟件可能會(huì)變得過于臃腫,有時(shí)只是因?yàn)橐恍┬⌒〉母倪M(jìn)把它推到了邊緣。 20. 目標(biāo)的改變 最初的計(jì)劃是建立一個(gè)數(shù)據(jù)庫來跟蹤客戶支出,以幫助制定營銷計(jì)劃。后來,一些天才又增加了一個(gè)功能,試圖利用人工智能來將消費(fèi)與天氣預(yù)報(bào)聯(lián)系起來?;蛘哂腥讼胱屵@個(gè)軟件自動(dòng)為搜索引擎廣告出價(jià)。改變目標(biāo)也可能會(huì)顛覆一個(gè)項(xiàng)目。 很少有變化會(huì)自己毀掉一切。但是新的目標(biāo)可能會(huì)揭示弱點(diǎn)并觸發(fā)失敗的模式。也許是這個(gè)團(tuán)隊(duì)現(xiàn)在太小了,無法成功地完成這個(gè)項(xiàng)目。也許是其技術(shù)基礎(chǔ)對(duì)于新方法來說非常低效??傊?,當(dāng)決定改變目標(biāo)時(shí),每個(gè)人都會(huì)很難預(yù)料到這些煩躁的組合。 (來源:企業(yè)網(wǎng)D1Net) |
|