神譯局是36氪旗下編譯團(tuán)隊(duì),關(guān)注科技、商業(yè)、職場(chǎng)、生活等領(lǐng)域,重點(diǎn)介紹國(guó)外的新技術(shù)、新觀點(diǎn)、新風(fēng)向。
編者按:李宏毅是新加坡總理李顯龍之子,不過他對(duì)從政并沒有興趣,而是更關(guān)心軟件開發(fā)和公益。他曾經(jīng)在Google工作過。后來又帶領(lǐng)團(tuán)隊(duì)開發(fā)了Parking.sg、Form.gov.sg以及Data.gov.sg等多個(gè)app和服務(wù)。李宏毅認(rèn)為,軟件身上的某些特征導(dǎo)致了很難用傳統(tǒng)的管理技術(shù)去開發(fā);而高效開發(fā)要求一種不同的,更具探索性和迭代性的方法。此文原刊載在新加坡政府網(wǎng)站上,原文標(biāo)題是:How to Build Good Software,是一篇有關(guān)軟件工程的佳作。36kr將其編譯出來,此為上半部分。
相關(guān)閱讀:新加坡政府推薦文章:如何開發(fā)出好軟件?(下)
這個(gè)世界上無法用金錢解決的事情不多,糟糕的軟件就是其中一個(gè)。大型航空公司做出來的航班搜索app經(jīng)常還比不上那幫學(xué)生做出來的。盡管既有的出租公司面臨共享乘車服務(wù)的威脅,但全世界的出租車公司的打車應(yīng)用都很糟糕。而那些用起來很痛苦的企業(yè)IT系統(tǒng)通常都是擁有大量預(yù)算的項(xiàng)目,而且這些項(xiàng)目都是用了多年的時(shí)間才開發(fā)出來的。所以不管軟件糟糕的原因是什么,似乎都跟沒錢無關(guān)。
令人吃驚的是,糟糕軟件的根本原因跟特定的工程選擇關(guān)系不大,更多是與如何管理開發(fā)項(xiàng)目有關(guān)。最糟糕的軟件項(xiàng)目通常會(huì)以非常特殊的方式展開:
項(xiàng)目業(yè)主一開始想要開發(fā)特定的解決方案,但又從來都沒有明確過自己想要解決的問題是什么。然后,他們收集了大量利益相關(guān)者的一連串要求。接著把這個(gè)清單交給外部相應(yīng)的大型開發(fā)團(tuán)隊(duì),由他們從頭開始去開發(fā)這一高度定制化的軟件。一旦所有要求得到滿足,當(dāng)系統(tǒng)發(fā)布,項(xiàng)目宣告完成時(shí),每個(gè)人都會(huì)彈冠相慶。
糟糕軟件的根本原因跟特定的工程選擇關(guān)系不大,更多是與如何管理開發(fā)項(xiàng)目有關(guān)。
但是,盡管這套系統(tǒng)技術(shù)上符合規(guī)范,但把它交到實(shí)際用戶手中時(shí)卻發(fā)現(xiàn)了嚴(yán)重問題。系統(tǒng)運(yùn)行緩慢,令人困惑,并充斥著難以捉摸的錯(cuò)誤,導(dǎo)致使用起來完全是一種充滿挫敗感的體驗(yàn)。不幸的是,此時(shí)外部開發(fā)團(tuán)隊(duì)已被解散,已經(jīng)沒有剩余資源來進(jìn)行必要的修復(fù)了。等到數(shù)年后再發(fā)起新項(xiàng)目時(shí),一切跟這些問題原因有關(guān)的知識(shí)已經(jīng)離開了組織,然后又來過一輪。
用什么樣的編碼語言,系統(tǒng)架構(gòu)或界面設(shè)計(jì)合適會(huì)因項(xiàng)目而異。但是,軟件特有的一些特征始終會(huì)導(dǎo)致傳統(tǒng)管理的做法失敗,但同時(shí)卻讓小型的初創(chuàng)企業(yè)用微薄的預(yù)算就能取得成功:
·重用好軟件很容易;這是讓你可以快速開發(fā)出好東西的奧秘;
·制約軟件的不在于投入到開發(fā)的資源量,而在于軟件在崩潰之前會(huì)變得多復(fù)雜;以及
·軟件的主要價(jià)值不在于生成的代碼,而在于編寫代碼的人所積累的知識(shí)。
了解這些特征也許未必能保證好的結(jié)果,但這確實(shí)有助于說明為什么這么多項(xiàng)目會(huì)產(chǎn)生不好的結(jié)果。此外,這還引出了一些核心的運(yùn)營(yíng)原則,利用好這些原則可以大大地提高成功的機(jī)會(huì):
開始要盡可能的簡(jiǎn)單;
尋找問題然后進(jìn)行迭代;以及
盡可能雇用最好的工程師。
雖然有很多更加微妙的因素需要考慮,但這些原則構(gòu)成了可以開始開發(fā)好軟件的基礎(chǔ)。
軟件很容易復(fù)制。就機(jī)械級(jí)這個(gè)層面來說,代碼行可以一字不差地拷貝粘貼到另一臺(tái)計(jì)算機(jī)上。通?;ヂ?lián)網(wǎng)上有很多有關(guān)如何用線上提供的現(xiàn)成代碼模塊來開發(fā)不同類型系統(tǒng)的教程?,F(xiàn)代軟件幾乎從來都不是從頭開發(fā)的。即便是最具創(chuàng)新性的應(yīng)用,也是通過組合和修改現(xiàn)有軟件開發(fā)出來的。
可重用代碼模塊的最大來源是開源社區(qū)。開源軟件的代碼可以自由發(fā)布,供任何人查看和使用。開源社區(qū)的許多最大的貢獻(xiàn)者都是科技巨頭。如果你想向Facebook那樣使用最先進(jìn)的可擴(kuò)展的數(shù)據(jù)庫(kù),只需下載他們?cè)?008年開源的Cassandra代碼即可。如果你想親自試用Google最尖端的機(jī)器學(xué)習(xí),請(qǐng)下載他們?cè)?015年發(fā)布的TensorFlow。用開源代碼不僅可以讓應(yīng)用程序開發(fā)更快,而且可以讓你接觸到比自己開發(fā)的任何技術(shù)都復(fù)雜得多的技術(shù)。而最流行的開源代碼甚至還更安全,因?yàn)橛懈嗳岁P(guān)注并及時(shí)修復(fù)漏洞。這就是數(shù)字技術(shù)能夠取得如此迅速的進(jìn)步的原因:哪怕是初出茅廬的工程師也可以利用上本行業(yè)最先進(jìn)的工具。
云服務(wù)的出現(xiàn)進(jìn)一步提高了可重用性,讓用戶只需訂閱費(fèi)即可完全使用甚至包括專有系統(tǒng)在內(nèi)的資源。想要個(gè)簡(jiǎn)單的網(wǎng)站?用Squarespace 或Wix 等建站服務(wù)就行了,點(diǎn)擊幾下鼠標(biāo)就可以配置好。想要數(shù)據(jù)庫(kù)?可以到Amazon Web Services或Microsoft Azure訂閱虛擬版。云服務(wù)使得開發(fā)人員從專業(yè)化中受益;安裝、維護(hù)都是服務(wù)提供商來做,并且不斷開發(fā)出優(yōu)質(zhì)可靠的軟件給所有訂戶使用。這樣軟件開發(fā)人員就不用再解決問題上浪費(fèi)時(shí)間,而是專注于交付真正的價(jià)值。
如果你把所有時(shí)間都花在重新開發(fā)已有技術(shù)上面的話,你是無法取得技術(shù)進(jìn)步的。軟件工程就是要開發(fā)自動(dòng)化系統(tǒng),而第一個(gè)被自動(dòng)化掉的東西就是常規(guī)的軟件工程工作。關(guān)鍵是要了解要重用的合適系統(tǒng)是什么,如何根據(jù)你的獨(dú)特需求去定制好,以及修復(fù)在此過程中發(fā)現(xiàn)的新問題。
軟件工程就是去開發(fā)自動(dòng)化系統(tǒng),而常規(guī)的軟件工程工作就是第一批會(huì)被自動(dòng)化掉的東西之一。
軟件的有用性通常受其復(fù)雜性的限制,而不是為了開發(fā)它所投入的資源量。
IT系統(tǒng)往往功能豐富,但用戶還是很討厭,因?yàn)樗鼈冏兊脤?shí)在是太令人困惑了。相比之下,排名靠前的移動(dòng)app往往因其簡(jiǎn)潔直觀而受到稱贊。學(xué)習(xí)使用軟件很難。到了一定程度之后,新功能其實(shí)還會(huì)讓用戶感覺更糟糕,因?yàn)槔鄯e下來復(fù)雜性開始變得不堪重負(fù)。比方說,iTunes作為蘋果媒體生態(tài)體系的樞紐已經(jīng)將近20年,到了今年終于拆分成了三個(gè)不同的應(yīng)用(分別用于音樂、播客和電視節(jié)目),因?yàn)樗墓δ軐?duì)于一個(gè)應(yīng)用來說已經(jīng)變得太過復(fù)雜了。從可用性的角度來看,限制不在于實(shí)現(xiàn)了多少功能,而在于如何融入到簡(jiǎn)單直觀的界面。
即使忽略了可用性,一旦項(xiàng)目變得過于復(fù)雜,工程進(jìn)度也會(huì)停滯不前。給應(yīng)用增加的每一行新代碼都有機(jī)會(huì)跟其他的每一行發(fā)生交互。應(yīng)用的代碼庫(kù)越龐大,開發(fā)新功能時(shí)引入的bug就越多。最終,制造出來的新bug的功率蓋過了開發(fā)新功能的功率。這又被稱為“技術(shù)債務(wù)”,是專業(yè)軟件開發(fā)的主要挑戰(zhàn)。為什么許多大型IT系統(tǒng)會(huì)存在多年未能解決的問題?這就是原因所在。為項(xiàng)目增加更多的工程師只會(huì)增加混亂:代碼庫(kù)瘦身之后,應(yīng)用反而跑得更快了。
開發(fā)好軟件需要擴(kuò)大和減少?gòu)?fù)雜性的交替循環(huán)。
在這種情況下,前進(jìn)的唯一方法是后退一步,把代碼庫(kù)合理化并進(jìn)行簡(jiǎn)化。可以重新設(shè)計(jì)系統(tǒng)架構(gòu)以限制意料之外的交互。了非關(guān)鍵的功能哪怕開發(fā)出來了也可以刪掉??梢圆渴鹱詣?dòng)化工具來檢查錯(cuò)誤和編寫錯(cuò)誤的代碼。比爾·蓋茨曾經(jīng)說過“靠代碼行數(shù)來衡量編程的進(jìn)度就好比靠重量來衡量飛機(jī)的建造進(jìn)度一樣”。人的頭腦只能處理有限的復(fù)雜性,因此軟件系統(tǒng)能變得多復(fù)雜要取決于這種復(fù)雜性預(yù)算的使用效率。
開發(fā)好軟件需要擴(kuò)大和減少?gòu)?fù)雜性的交替循環(huán)。。隨著新功能被開發(fā)出來,失調(diào)就會(huì)在自然地在系統(tǒng)中積累。當(dāng)這種混亂開始引起問題時(shí),開發(fā)工作就得放一放以騰出時(shí)間去清理。這兩步是必要的,因?yàn)榘乩瓐D式的好設(shè)計(jì)根本就是子虛烏有:這要取決于你的需求以及你遇到的實(shí)際問題。即便簡(jiǎn)單如如Google搜索欄這樣的用戶界面之下也隱藏著龐大的復(fù)雜性,而這些復(fù)雜性是無法在一次迭代中得到完善的。挑戰(zhàn)在于要管理好這個(gè)循環(huán),讓它變得足夠混亂以取得有意義的進(jìn)展,但又不要讓它變得太過復(fù)雜以至于不堪重負(fù)。
柏拉圖式的好設(shè)計(jì)根本就是子虛烏有:這要取決于你的需求以及你遇到的實(shí)際問題。
在軟件開發(fā)中,大多數(shù)想法都是很糟糕的;這不是誰的錯(cuò)。那只是因?yàn)榭赡艿南敕〝?shù)量太多了,多到哪怕非常小心謹(jǐn)慎以及明智地做出選擇,任何特定的想法可能都未必見效。要想取得進(jìn)展,你需要從一堆糟糕的想法開始,拋棄最壞的想法,然后逐步形成最有希望的想法。蘋果就是富有遠(yuǎn)見設(shè)計(jì)的典范,蘋果在推出最終產(chǎn)品之前會(huì)經(jīng)歷幾十個(gè)原型。最終產(chǎn)品看起來可能好像很簡(jiǎn)單;但其背后卻是非常錯(cuò)綜復(fù)雜的認(rèn)知的結(jié)果,他們是在對(duì)比了替代方案之后才選擇出特定解決方案的。
即使在產(chǎn)品被開發(fā)出來之后,這種認(rèn)知仍然很重要。如果新團(tuán)隊(duì)接管了自己不熟悉的軟件代碼,這部分軟件很快就會(huì)出現(xiàn)退化。操作系統(tǒng)會(huì)升級(jí),業(yè)務(wù)需求會(huì)變化,會(huì)發(fā)現(xiàn)需要修復(fù)的安全問題。處理這些微妙的錯(cuò)誤往往比一開始開發(fā)軟件還要難,因?yàn)檫@需要對(duì)系統(tǒng)的體系結(jié)構(gòu)和設(shè)計(jì)原則有深入的了解。
在短期內(nèi),不熟悉的開發(fā)團(tuán)隊(duì)可以靠臨時(shí)修復(fù)來解決這些問題。但隨著時(shí)間的推移,由于額外代碼的權(quán)宜性,新錯(cuò)誤會(huì)累積。由于設(shè)計(jì)范式不匹配,用戶界面變得混亂,并且整個(gè)系統(tǒng)的復(fù)雜性增加。軟件不應(yīng)該看作是靜態(tài)的產(chǎn)品,而應(yīng)視為開發(fā)團(tuán)隊(duì)共同理解的生動(dòng)體現(xiàn)。
軟件不應(yīng)該看作是靜態(tài)的產(chǎn)品,而應(yīng)視為開發(fā)團(tuán)隊(duì)共同理解的生動(dòng)體現(xiàn)。
這就是為什么依靠外部供應(yīng)商來進(jìn)行核心軟件開發(fā)很難的原因所在。你也許會(huì)得到一個(gè)能跑的系統(tǒng)及其代碼,但是有關(guān)它是怎么開發(fā)的,以及為什么做出這樣的設(shè)計(jì)選擇的寶貴知識(shí)卻被帶走了。這也是為什么把系統(tǒng)交給新供應(yīng)商進(jìn)行“維護(hù)”往往會(huì)導(dǎo)致問題的原因。即使系統(tǒng)進(jìn)行了很好的存檔,每次新團(tuán)隊(duì)接管時(shí)都會(huì)丟失了一些知識(shí)。慢慢地,這套系統(tǒng)變成了許多不同作者的代碼拼湊而成。繼續(xù)運(yùn)行變得越來越難;到最后,再也沒人能真正理解系統(tǒng)是如何運(yùn)作的。
為了讓軟件長(zhǎng)期保持運(yùn)轉(zhuǎn)良好,在外部幫助下讓你的員工跟著一起學(xué),這樣可以讓關(guān)鍵的工程知識(shí)留在你的組織之內(nèi)。
譯者:boxi。
本文來自翻譯, 如若轉(zhuǎn)載請(qǐng)注明出處。
聯(lián)系客服