# 第 1 章 軟件開發本質論
關于軟件以及軟件開發,已經有很多定義、介紹和專業的解說。在進行代碼編寫前,或者說在正式進入軟件開發這一領域前,我們有必要對當前的時代背景,以及軟件開發所面臨的問題,所應對的解決方案再簡單溫習一下。
## 1.1 信息與價值
中學的教科書告訴我們,人類社會分別經歷了農業時代和工業時代,而現在正處于信息化時代。
根據全球通史的介紹,人類由于耕種技術的成熟,從游牧狩獵進入了農業時代,定期收割的大量食物保障了人們不受饑餓而迎來了人口的激增。到了工業時代,世界到處是尚未開采的礦石、材料、石油、能源,這時通過蒸氣機和電動機等產生的巨大能量,使得這些遍布世界的資源能快速流通,從而造就了人類財富的快速增長,隨之而來的則是人們生活水平的又一次極大提升。
如今,信息量以指數級的速度增長,產生了爆炸性的海量數據。曾有數據指出,如今一天的信息量,就遠比19世紀80年代華盛頓郵報一年產生的信息還要多。縱使如此,人們還是比以往需要更多的信息。以我母親為例,自從使用微信后,就每天都在看朋友圈、和親朋好友發語音、視頻聊天,此外還瀏覽各種新聞資訊信息,學習養生健康知識等。雖然她才剛剛學會使用智能手機不久。這是我們日常生活中的例子,也是作為對信息使用的常見例子。
在現實的物理世界中,有物質守恒和能量守恒定律。作為高中選修物理學科的我相信,同樣在虛擬的互聯網世界中,也存在著信息守恒定律。即信息不會憑空產生,信息也需要經歷產生、收集、處理、傳播等一系列操作。通俗來說,信息在被使用前,需要先產生。我們很容易發現身邊使用信息的現象,因為我們正處于一個信息無處不在的時代。例如我們可以看到這一周有哪些即將上映的電影,可以在網上進行購物、在線支付,可以使用手機新聞客戶端隨時查看世界各地發生的奇聞趣事,可以預訂下周出國旅游的飛機票,可以通過遠程辦公處理商業事務。
正如每次社會變革來臨一樣,總會發生一些巨大的變化。善于觀察,敢于冒險和有商業頭腦的人,會從這些錯綜復雜的信息中發現商機,從而創造財富。而作為從事軟件開發的技術人員,我們應當從中看到信息處理、加工、傳播這一過程背后需要的技術與軟件支持。可以說,那些善于使用各種信息資源的百姓,在生活、工作和學習上都會獲得極大的便利;那些善于將信息與其他資源整合,并為需要的人提供服務的商人,在財富上會有極大的積累;最后那些善于開發軟件,為商業提供信息化技術支持,并能快速響應市場變化,滿足客戶需求的程序員,將能創造出更大的商業價值,同時實現更大的自我人生價值。
在更短的時間內,通過開發軟件,滿足人們對信息的最大化需求,從而間接幫助提升人們的工作效率、提高生活水平,將是我們作為軟件開發工程師引以為豪的事情。
反過來講,那些成為行業巨頭或者世界500強的公司,很多都是對信息進行了價值最大化處理的公司。例如谷歌為全球提供了非常強大的搜索功能,臉書為十幾億用戶提供了交流平臺。同樣,這條規律也適用于我們程序員個人。個人職位的晉升、所獲得的工資收入、在技術上的成長與收獲、在行業內的聲望和地位,是對我們多年從事信息化工作和科技類工作,或直接或間接的嘉獎。
對于在公司就職的開發人員,如果你覺得是在為上級領導而工作,這是片面的;如果你認為是在為公司而上班,這是不全面的;本質上,我們都是在為了社會,為了與日俱增的信息而工作。
這就是我們所處的大時代,大背景。
## 1.2 代碼,軟件和價值
作為一名軟件開發人員,我希望可以:**致力于編寫容易理解的代碼,專注于軟件開發領域,努力創造更大的價值**。
### 1.2.1 編寫容易理解的代碼
最近比較流行“工匠精神”,搜了一下,百科解釋如下:
> 工匠精神,是指工匠對自己的產品精雕細琢,精益求精、更完美的精神理念。
在編寫代碼時,我們也能親近深切地體會到這一過程里微妙的精神。
對于一個功能的代碼集,再到一個函數的代碼塊,最后到可執行的一行代碼甚至是一個變量的命名,我們可以粗糙地實現功能即可,也可以按照良好的設計、遵循統一的代碼風格、結合測試驅動開發進行小步重構,還可以再進一步深入思考、探索應用業務領域,從而編寫出能夠存活很久并仍具有活力的浮現式代碼。
可能會有同學覺得,需求總是那么趕,留給開發的時間總是那么少,又要調試,又要修bug,還要開會聯調等等,沒有那么多時間對所寫的每一行代碼進行精雕細琢。但是,我們能不能反過來想,會不會是因為我們還沒具備比較良好的專業素養和技能,未能在短時間內一步到位交付高質量的代碼,才導致需求迭代不夠順暢呢?
現在有多混亂,以后就有多痛苦。
如果說編程是一種藝術,那么在開發項目時,我們應該把項目當作一個藝術品來創作。既然我們開發人員作為軟件系統這一藝術品的創造人,那么就應該是由我們來決定何時(當然應該是在合理的排期內)交付產品,而不是迫于需求方的時間壓力就隨意交付次品。因為根據守恒的定律,研發一個高質量產品所需要的時間是一定的,現在為了趕進度,投入的時間和精力少了,那么日后維護時就需要更大的成本來填補曾經所留下的坑。
那么問題來了,受限于局促的開發時間,又要交付高質量、有價值的產品,我們應該怎么做?參考中學時代的這一公式:
```
路程 = 速度 * 時間
```
我們可以類似得出這樣的開發公式:
```
產品 = 開發速度 * 時間
```
所以當所需要的產品功能點和開發時間是固定時,要想在預期的里程碑內按時交付,我們只好提高自身的開發速度了。提高效率其中一個途徑就是少返工,一步到位,把所發現的問題以及可預見的問題在開發初期就早早地解決,這些都要求我們能夠編寫出容易理解的代碼。正如托尼·霍爾所說的:
> 設計軟件有兩種方法:一種是簡單到明顯沒有缺陷,另一種復雜到缺陷不那么明顯。
尤其是現在,計算機的硬件成本已經越來越廉價,曾經開發者前輩需要排隊才能用得上大型計算機,現在隨手都是筆記本這些智能移動設備,而且花幾十塊錢就能租到一臺24小時運行的服務器。相比之下,人的成本則越來越高,而且人的工作效率在某種程度上容易受到情緒的影響。只要能通過編譯的代碼,計算機都可以不斷重復完美地精確運行并得到期望的結果,不管代碼是匯編寫的還是高級語言寫的,也不管代碼有多么丑陋。但如果開發人員看到難以理解的代碼,會大大增加理解成本,而且心情煩躁,產生抵觸心理,進而導致開發不順暢,障礙重重。畢竟,程序員的快樂,更多在于創造,而不是維護歷史遺留系統。但如果原來的代碼是短而美,那么將會是另一番景象。
作為外行人士,他們可能關注的是產品界面好不好看,交互夠不夠人性化這些表面的東西,但作為內行,作為開發人員,我們應該關注隱藏在系統背后的代碼是否規范,是否能讓別人容易理解,是否能夠恰到好處地體現所要表達的意思。
不管怎么說,編寫容易理解的代碼,總是會有好處的。
### 1.2.2 專注于軟件開發領域
我剛畢業時,我的Team Leader兼導師不止一次地告誡我:不要只限于技術。誠然,我覺得程序員所學的東西也不要局于代碼,所做的事情也不要局限于編碼。作為開發人員,代碼是我們和外界交流、交互的媒介,也是我們用于構建有價值服務的基礎,但除了關注代碼,我們還需要關注軟件開發這一領域,還要深入了解探索軟件開發的各個方面,才能更有把握交付成熟穩定的系統。
如果想要給家里的花園砌一道墻,那么只需要掌握把一塊塊磚頭和攪拌好的水泥粘合在一起就差不多了,即便不美觀,但能夠起到防護的功能也算是一道很好的墻。但如果需要建筑的是一個客流量高達成千上萬的大型商場,那么除了要掌握砌墻外,還要掌握排水通風、防雷抗震、商場的業務性質、各個店鋪的設計等一系列問題,這時就不再是建一道墻那么簡單,而是相當于構建一個復雜的系統。
同樣,在軟件開發中,我們要構建的系統越大、價值越大,就要求我們所要掌握的范圍面更廣,要考慮的因素就越多。因為這時,軟件開發是一門工程,一門需要團隊一起交流、協助、共同努力完成既定目標的工程。
專注于軟件開發領域,意味要專注于復雜系統、軟件工程和跨學科的融合。
### 1.2.3 創造更大的價值
以前一百萬人養活一個君王,現在一個天才就能養活一萬多人。
當然,不是每個人都能成為天才,但我們作為軟件開發工程師,可以通過軟件創造更大的價值。
某種程度上,軟件開發也是一種服務,它服務于特定的用戶。但不同銀行的業務窗口,速度慢而且同一時間一個業務員只能服務于一個客戶,相反,我們的軟件一旦開發完成發布上線后,就可以同時服務大量的用戶,而且還可以是遍布世界各地的用戶。可想而知,所能創造的價值有多大。
一個包子做好了,只能給一個人吃(當然也可以分著吃),所以包子鋪老板創造的價值,相比之下不會特別大(這里完全沒有其他意思,對于辛勤勞動的人民,我總是致于崇高的敬意)。而且,包子鋪老板要是哪天休息放徦了,他就沒有包子可賣,自然就沒有創造新的價值。值得慶幸的是,開發好的軟件系統與此不同,軟件不僅能同時服務于大量的用戶,而且一旦發布上線后,我們就可以抽身繼續開發新的軟件,不斷創造更大的價值。我覺得這是一件很棒的事情!
想一想,如果有成千上萬的人們使用我們開發的軟件,那是一件多么讓人激動的事情。真正讓我們興奮的不是我們所研發的產品出名了,而是我們的產品每天都被人們在生活中不斷使用,被依賴,被需要。
我一直認為,開發出來的軟件,應該是能夠幫人們解決某種問題,如提升工作效率、幫助更好地學習、或是改善生活,而不是給人們帶來苦惱,帶來壓力。我很慶幸我這一生能有機會一直從事我所深愛的職業——軟件開發,也非常慶幸我能有創造更大價值的機會。
當然,能力越大,責任越大。
如果處理得不好,我們也會面臨項目夭折,或是交付有諸多問題的產品,甚至是系統上線運行后出現故障而導致損失重大。所以,在這里,我希望能通過分享一些自己的經驗和總結,幫助更多的同學提升開發效率,了解軟件開發這一領域,一起創造更大的價值。
## 1.3 一行代碼值多少錢?
一個問題的意義,不僅在于解決了這個問題,更在于通過這個問題引伸出更多富有意義、更具挑戰性的問題。我們將嘗試探索“一行代碼到底值多少錢”這一問題,進而通過這個問題,引出更多深層次的問題,最后收斂于線上故障。
### 1.3.1 簡單的計算
最簡單粗暴但明顯是錯誤的計算,假設一位開發工程師的月薪是1W,按每月22天折算,其工價約為:1RMB/分鐘。又假設,寫一行代碼,平均需要10分鐘。
用一張邏輯推斷圖表示即:

圖1-1 一行代碼值10 RMB
這是局限于開發人員個體在單純進行編寫一行代碼本身所需要的造價,這明顯是不全面的,因為還沒考慮開發人員在編寫這行代碼之前進行需求分析、領域模型設計所需要花費的時間,更不用說與其他干系人在項目開發過程中進行的溝通協作成本。
但這很可能正是很多人眼中或潛意識中錯誤認識的觀念:寫一行代碼不是幾分鐘的事情嗎?由此暗示一行代碼低兼的造價。
實際上,真的是這樣嗎?一行代碼,真的只是值10塊錢嗎?
### 1.3.2 進一步地計算
更為合理地評估一個項目的經費,應該是從完成交付的系統功能點以及開發團隊為此付出的精力和時間這兩方面進行衡量。如果只是單純按代碼行數來計算,則會導致開發人員本來用一行代碼完成的事情分拆成N行,而不是激勵程序員編寫更短更美更達意的代碼。
這樣,進一步計算,我們可以把功能點和投入的時間所需要的成本,再平均分攤給每一行,從而也可以得出每一行代碼值多少錢。繼續用一張邏輯推斷圖表示即:

圖1-2 一行代碼值55 RMB
這似乎更為合理,因為我們考慮了更多的因素。但,一行代碼,真的就只值幾十塊錢嗎?
### 1.3.3 未知的損失
如何計算一行代碼到底值多少錢,我覺得,不僅要考慮已知的成本,還應涉及未知的損失。即:

圖1-3 一行代碼值多少錢?
損失即存在的風險,既包括了可預見的風險,還包括了不可預見的風險。而造成的損失則會根據影響的時長、涉及的用戶數以及對現實世界造成的損害和為此而付出的代價而定,小則幾百,大則上萬。況且,還有很多損失的代價是不能直接從經濟方面衡量的,甚至是不可逆的慘痛教訓,例如對品牌形象的損害。
所以,一行代碼值多少錢,不僅要考慮溝通、測試、開發、文檔、部署、宣傳、維護的成本,還要考慮由于代碼問題而損失的代價。
假設某次故障導致的損失為5W,而最終導致故障發生的原因為代碼問題,并且假設出錯的代碼只有一行,那么這行代碼則處于關鍵的位置,并價值甚大。
在我曾任職的公司里,我就因為一行代碼造成商品無尺碼顯示的線上故障,當時由于導致用戶無法購買,評估的損失約為數十萬。而這次故障正是因為一行代碼而導致的!
### 1.3.4 淺談損失
造成的損失,不僅有因為做錯過什么而導致的損失,還有因為沒做什么而造成的損失。
+ 該做異常處理的卻沒捕捉導致程序crash異常退出;
+ 該做超時重試的卻沒設置導致進程無限等待最終導致服務器內存耗盡;
+ 該做SQL注入防范的卻沒轉換導致數據庫被入侵甚至泄露敏感用戶數據,一如賬號密碼;
+ 該做負數判斷的卻沒檢測導致在金額消費扣除時負負得正,反而錢越花越多。
而這些,對應的解決方案,
+ 可能需要聯系各個渠道重新全量發版以修復用戶app崩潰的問題;
+ 可能需要緊急發布以修復服務器集群運行到一定時間就突然down機的奇怪現象;
+ 可能需要統一對外公告并告知用戶及時修改密碼;
+ 可能需要開發人員不僅要修復上線,還要花好幾天的時間排查各個用戶的日記,通過grep找出不合法的“充值”紀錄然后追蹤其消費流水過程,進行相應的處理甚至封號、列入黑名單。
“做錯過什么”是不小心而為的,“沒做什么”中很多時候明知多做一點就能預防,卻因為一時偷懶、僥幸而沒做,最終在生產環境被觸發,繼而放大,釀成故障,實在是不應該。
### 1.3.5 一行代碼的生命歷程簡史
若把每一行代碼都比作是有生命的小個體,我想它終其一生也許會是這樣的:
當開發人員按下Enter回車鍵后,一行由特定的字符排列而成的代碼就從混沌中誕生了。當它的“創世者”點擊保存后,這一行代碼就來到了人世間。那時,一切都還很平靜,它既感到好奇又覺得陌生,于是便和身邊的小伙伴親切交流了起來,以便彼此互相認識。隨后,開發人員會把它提交到版本控制系統,進入到質量測試環節。
這時,會有一些專門的測試團隊會找出編寫不合理的代碼并反饋給開發進行相應調整。經過多次打磨,在投入到真正的戰場前,它還要走過一段漫長的道路,如持續集成、回歸測試、灰度發布等。
最后,它們被部署到了最終真正線上的環境,一個更為復雜、嚴酷、激烈的環境。每時每刻,它們都在 CPU中穿梭運行,每天處理了上百萬次的請求,接收/輸出上T級的數據,為各種各樣的用戶提供著有價值的服務。在這些用戶中,除了有正常的用戶,還有一些惡搞的用戶、非人類的用戶,諸如:爬蟲、機器人、搜索引擎等等。有些用戶會嘗試從這一行行的代碼獲取他們需要的業務功能,有些用戶則會嘗試獲取一些更高級但非法的功能,甚至有些不懷好意的用戶則試圖發現極有破壞性的代碼行,然后觸發它……
當它老了,需要退役時,應當能夠做到優雅地退出歷史舞臺而不會給現有的系統造成其他影響,否則會變成熔漿式代碼,影響后生的代碼。
可以說,每一行代碼所處的環境,都是已知的,但又是未知的。
已知是因為我們知道它在那個位置需要擔當什么功能,實現什么業務;未知因為沒辦法完全了解它會面臨怎樣的系統平臺、怎樣的數據、以及怎樣的用戶、怎樣的一個處境。
這要求我們在寫每一行代碼時,不僅需要知道編程語言本身的語法特性,還要了解它的運行機制、原理,還要清楚需要實現的業務功能,還要能考慮到它未來將會運行于怎樣的一個場景下,最難得可貴的是,可以深入考慮到它將會面臨怎樣的重大問題,包括功能性的以及非功能性的。
也就是我們通常所說的可擴展性、安全性、穩定性這些質量屬性,正是由這一行行的代碼日積月累、聚合而成的。
### 1.3.6 如何寫出好的代碼
終其代碼的一生,我們需要在一開始就為它將要面臨的問題與挑戰做好充分的準備。每個問題之所以會發生,都是因為我們想得還不夠深入。只要我們再想多一點,就可以避免重大問題的發生。而且,往往我們覺得會有問題發生的可能時,往往都就發生。
何謂好的代碼?好的代碼,就是一行也不能少,一行也不會多。
好的代碼,應該是高度自治的,即它不會以損害其他的代碼為代價來完成自己的事情或功能。而是應該本身是健康的,既無腐蝕性,又對系統不具入侵威脅,反而能幫助其他的代碼行一起完成重大而嚴謹的使命任務。同時能適應更多的情境。
反觀過往的經驗,問題發生的節點更多在于與外部系統的交互上,比如調用了遠程的接口而沒有設置超時而陷于漫長等待,進行了數據庫訪問而沒考慮到并發量而導致了阻塞,調用了Android的系統API而沒進行版本判斷而導致崩潰。
出現問題的代碼,通常都是脆弱、不規范、有問題的代碼。
因為代碼的編寫原則和規范都有很多相關說明,下面再簡單補充一下:
+ 遵循慣例
+ 忠于代碼本身
+ 功能導向
+ 考慮上下文
+ 能夠適應更多的環境
下面分別說之。
#### 遵循慣例
各個語言都有語法上微妙的容易犯的錯誤,一如:
+ 10 Most Common PHP Mistakes
+ The 9 Most Common Mistakes That Ionic Developers Make
#### 忠于代碼本身
在編寫一行代碼時,我們應當理性地進行編寫,而不應感性地編寫。也就是說,我們應該遵循編碼的開發規范、滿足項目面臨的約束、保持系統架構的風格和原則。再直白一點,這一行代碼的結果需要加強判斷的則加強判斷,這一行代碼需要考慮容災的則添加容災,這一行代碼需要向前兼容的則向前兼容。
而不能因為我本來也知道需要進一步完善的,但因今天心情不好、或因需求頻繁變動而有抵觸情緒,或抱著可能不會發生的僥幸心理,使得應當加強的沒加強,應當容災的沒容災,應當兼容的沒兼容,最終導致線上重大的故障發生。這屬于感性編程,而非始終忠于代碼本身功能的專業體現。
存在即合理。但我們也可以反過來理解:代碼因為合理而存在。不合理的代碼,即有缺陷的有bug的代碼,最終還是會被修復優化、甚至被移除的。既然,一開始就可以做好的事情,為什么要付出代價后才肯回來彌補呢?
#### 功能導向
在我剛畢業時,曾就職于一家游戲公司。當時我很自然地敲出以下操作命令:
```
$ php ./all_in_one.php >> run.log 2>&1
```
而站在一旁的一位資深架構師(也是我頗為敬仰的大神)突然問我:你知道這行命令的意思嗎?當時,我愣住了。仿佛回到了當年校招面試時被問到了一個完全不懂的問題,一臉不知所措。更為尷尬的是,我一直在使用這樣的命令,它每個參數的作用我竟然不知!
所以在寫每一行代碼時,都需要知道它確切的意思,各個參數的作用,內部的原理,與其他類似接口的微妙關系與區別。需要多想想,多查查,這一行代碼是否能很好地勝任我們將要賦予給它的任務?我們需要用它來做什么,我們又不需要它在背后做什么?
#### 考慮上下文
**一切不考慮上下文場景的代碼,都是耍流氓。**
在一次性能優化中,我們發現有一行代碼被調用了17K次!幾乎占用了接口響應時間的10%!
絕大多數的情況下,以下這樣的寫法都是沒有問題的:
```
$bufLength = TStringFuncFactory::create()->strlen($this->buf);
```
而且我們也確實看不出有什么問題。這是一個很好的封裝,也使用了工廠方法模式,可以說這是一行很合格且寫法清晰的代碼。再來看下TStringFuncFactory::create()內部的實現,也是使用了單例模式,沒有特殊之外。但令人頗為驚訝的是,在xhprof的報告中,我們發現此函數竟然被調用了17K次!
回顧TStringFuncFactory::create()被調用的場景,我們從圖中,可以看出TFramedTransport::read()竟然調用了11,700次!最終優化后,調用次數從17K降到了只有100多次,三個級別的差距!為了有一個更形象的對比,若用米作為單位,試這樣粗算對比前后優化的效果:
表1-1 優化前后的調用次數對比
|函數調用次數|等效的長度(單位:米)
---|---|---
優化前|17K次|相當于田徑場跑44圈
優化后|100多次|相當于百米沖刺的距離
優化前,相當于田徑場跑44圈;優化后,相當于只有百米沖刺的距離!值得提醒的是,實際的優化效果與接口返回的報文長度成正比。報文長度越大,差距越明顯。關于這部分的信息,后面會再來詳細講解。
#### 能夠適應更多的環境
軟件開發發展至此,已大概有30多年。我們所編寫的代碼,最終會運行于不同的平臺、不同的系統、不同的硬件、還需要配套不同的外部系統或依賴系統,以及各編程語言的支持,而這些平臺、系統、硬件、外部系統、編程語言又會分為不同的版本。
這就有點像,一行弱小的代碼,被扔進了一個錯綜復雜的世界,不僅需要滿足各個霸主苛刻的要求,還要面對不可預見的未來——因為它不知道將會接收處理怎樣的數據。此時,我們應當考慮到代碼的健壯性,以便它能適應更殘酷的環境。
任何問題,最終都是團隊問題,而不是個人問題。正如《清單革命》說道的那樣:團隊犯錯的概率會更低。我們應該充分發揮集體智慧,賦予代碼更頑強的生命力,從而適應更苛刻的環境。
代碼雖小,影響甚大。
## 1.4 問題域和解空間
軟件行業自誕生以來,就如同一個懵懂的小孩一直在跌跌撞撞,愉快而艱難地成長著。在這過程中,我們遇到了很多前所未有的問題與挑戰,也提出了飽含智慧、成熟的解決方案。但依然,形勢是嚴峻的。每天,還是會有很多項目失敗在途中,在還沒公布于眾之前就悄無聲息了。每天,依然有各種故障、Bug、漏洞、項目延期等困擾著我們,即便很小的系統也難逃此命運。
為什么會這樣呢?為什么在建筑行業隨處而立的高樓大廈過了百年仍能穩如泰山,為什么我們一個小小的網站都會問題多多?
是的,軟件行業還很年輕。關于行業的標準、規范,我們還沒形成共識。從現實世界映射到軟件虛擬世界,需要一個建模的過程。對于特定領域業務來說,這個建模的過程可以更方便地在軟件開發工程師與領域專家之間建立起溝通的橋梁。單單對于這一領域建模過程,我們也都還未建立起公認的體系,甚至有些專業開發人員都不知道或者認為不需要這一過程。
我個人覺得,在需求現實世界和軟件虛擬世界之間進行建模是很有必要的,并且越發傾向和支持問題域和解空間這一說法。
在《領域驅動設計》中,Eric為我們介紹了軟件核心復雜性應對之道。他的真知灼見明確告訴了我們如何結合實體、服務和值,以及上下文綁定、釋意接口等“大聲地”構建領域模型。只有當我們對項目的需求,對系統將要實現的領域業務有深刻的理解和認識后,我們才能更有效地對其進行設計、開發、測試、集成和交付。試想一下,如果客戶想要實現的是無人汽車駕駛智能系統,而我們因為誤解而最后交付的是二手汽車拍賣平臺,那會是怎樣一個結果?
在對特定領域進行恰如其分的建模后,我們才能更好地把捏項目的需求,然后進入正確的迭代流程。還是那句話:做正確的事,比把事情做正確更重要。
軟件會越來越復雜,越來越龐大。有開發經驗的技術人員會很容易發現,開發一個新功能的難度并不在于它的本身,而是在于如何在現有錯綜復雜的系統中,準確無誤地嵌入這個新功能。如果一開始的問題域理解有誤,所選擇的解空間也就難以與系統本質的領域匹配。這無疑是雪上加霜,偶然的復雜性再加上本質的復雜性。
準確理解問題域后,后面的事情就相對好辦了。鑒于各項不斷涌出的新技術,以及過往既有的成熟解決方案,我們可以根據項目的特點進行技術選型,構成與問題域對應的解空間。但這個解空間,包含的內容和知識,以及實踐、理論、標準非常之多,需要我們投入大量的時間和精力來研究和操作。
就如網站前端開發來說,除了要掌握Javascript、HTML、CSS這些基本的編程技術外,還要了解HTTP/HTTPS協議、CDN加速,不同瀏覽器的標準、支持度和兼容性,以及H5混合應用開發,打包壓縮和構建等等。基本每一個細分的專業崗位,都有一系列完整的學習路線。
你,準備好了嗎?
## 1.5 不要急,但要快!
經典武俠小說經常會說道,天下武功,唯快不破。在我們軟件開發領域,也有著類似的說法:不要急,但要快!
一個軟件產品的生命周期,通常都會比較短,因為產生的軟件太多,淘汰率太高。即便是成熟成功的軟件系統,也需要不斷自我更新,自我變革,否則就會容易被市場淘汰。人們對信息日益增長的需求,加上全球化的影響,如今市場的變化是日新月異,這造成了軟件開發需求的頻頻變更。此外還有政策變化的影響,很有可能,某一天政府出臺一條政策,并要求企業對此迅速作出響應和整改。公司則需要找出相關技術負責人進行修改調整,甚至加班加點趕這需求。
不管怎樣,不管出于何種原因,我們將要面對的都是變化節奏比以往任何時候都要更快的社會。這勢必會要求在互聯網行業內的我們,時時刻刻,都要快速響應。需求分析要快,設計要快,開發要快,測試要快,上線要快,修復Bug要快,反饋要快,推廣要快!
再說一次:做事情,不要急,但要快!
## 本章小結
信息即價值,信息量越大,蘊藏的價值就越高。軟件開發所從事的工作正是通過有效的方式來開采這個信息金礦。為了做正確的事情,我們需要通過領域建模準確理解問題域,然后找到與之匹配的解空間。簡單了解一些理論后,接下來讓我們進入實戰部分。