技術選型指南

這是一篇綜合類技術選型指南,試圖爲你提供一份比較通用的技術選型思惟框架。當你須要進行技術選型時,能夠參照它來設計本身的決策樹。這其中你須要考慮的主要維度包括目標產品、目標用戶、目標團隊和技術自己,下面我將分別細述,並在此基礎上介紹一些反模式。前端

維度

目標產品

這是最重要的維度。產品自己的特徵將影響技術選型時的不少因素。程序員

短生命週期產品和長生命週期產品編程

短生命週期的產品一般要求快速起步:門檻低、書寫自由、不強制遵循任何最佳實踐。當它的使命結束時,代碼會被直接拋棄。因此,對於這類產品,「快糙猛」的技術是較好的選擇,固然,能作到「快精猛」更佳。後端

而長生命週期的產品則會強烈要求可維護性,由於它們在很長時間內都是不可報廢的。甚至對於一些生命線產品,連重寫都會要求在重寫期間線上系統平穩過渡,一點點遷移到新技術。瀏覽器

這種要求對團隊的工程化能力是個極端的考驗。若是沒有相應的工程能力,其代價甚至會高於用新技術從新寫一個功能相同的系統。微信

探索型的產品和守成型的產品架構

探索型產品每每也是短週期產品,可是同時也有本身的特色。它要求快速,但每每同時會要求高質量。探索型的產品若是證實了可行性,那麼過渡到長生命週期的可能性很大。框架

這就要求它最好是一個微內核系統,提早留出一些擴展的空間。固然,設計微內核系統對架構師的能力具備至關的考驗,若是沒有一個優秀的架構師,建議仍是不要刻意作任何預留,優先保障系統的簡單性。運維

除此以外,探索型產品的技術棧必須支持可靠的、自動化的重構。由於探索型產品的迭代速度很快,若是徹底靠人工去添加功能並手動重構,那麼一旦出現 BUG,將給此產品的用戶體驗帶來嚴重的負面影響。性能

因此,除非因爲人才儲備等緣由而被迫作出折中,不然探索型產品的技術棧必定要快速而嚴謹。

固然,「大力出奇跡」定律也是成立的。也就是說,若是你有決心也有力量在未來對這個探索型產品進行完全的重寫,那麼採用快糙猛的技術快速把它搭建起來,也何嘗不可。若是你的業務確實能如預期般爆發,那麼只要把重點放在系統延展性等方面便可;可是若是不能如預期般爆發,可能就會致使維護成本在中期開始飆升,在競爭中處於劣勢。這是一種「不成功便成仁」的策略。據我所知某獨角獸企業就是在業務起來以後經過鉅額投入來償還技術債的。但這對於 CTO 的技術直覺是一項極大的考驗,不要輕易效仿。

而對守成型產品的選型則會側重於與現有技術棧的類似程度和無縫整合能力。若是整合時須要藉助不少技巧,那麼可能你就是在給本身挖坑。

在引入新技術的過程當中,要儘量符合現有的開發流程、基礎設施和開發習慣。固然,若是現有的這些已經嚴重過期,那麼應該找新老技術的專家,共同幫你設計一個路線圖,讓你能夠平穩地引入新技術,這份投資絕對值得。若是老技術已經有新版本,則應該優先考慮升級它。不要幻想換個技術棧就能解決一切問題,事實上,它帶來的問題每每會更多。

邊緣產品和生命線產品

在人員的學習能力和意願容許的前提下,邊緣產品是最佳的試驗場,適合探索各類候選技術,試驗各類激進方案,積累經驗教訓。其影響範圍可控,即便失控也不會帶來太大的損失。固然,即便探索,也應該有計劃地探索,不要每一個邊緣產品都採用不一樣的技術方案,那樣會給人才供應帶來巨大的挑戰。

而生命線產品則應該穩妥優先,採用保守方案。因此應該優先採用團隊內部積累了必定經驗或具備穩定的強力外援的技術。

全部的生命線產品幾乎必然是長週期產品,因此其可維護性一樣是重中之重。

產品維度總結

在目標產品維度上,低價值產品優先考慮門檻低的技術,可是高價值產品應該儘早進行投資性技術積累,優先考慮天花板高的技術,這樣纔不至於在若干年以後被迫重寫。若是工程化能力不足,這種重寫每每會成爲災難。

目標用戶

用戶的特色對於技術選型具備顯著的影響,甚至可能會致使產品不可用。

瀏覽器版本

在前端領域,瀏覽器版本是永遠的痛,但這是須要權衡的。高版本瀏覽器甚至是單一的低版本瀏覽器會顯著節省開發成本,可是可能會損失一些用戶。該怎麼解決呢?固然不能拍腦殼決定。

若是大家已經有同領域的線上系統,那麼應該統計這些線上系統的訪問狀況,得出一個最準確的、針對目標客戶羣的統計,而後分析一下不一樣版本的瀏覽器有多大價值,有沒有可能經過非技術手段讓用戶使用大家的目標瀏覽器。即便沒有線上系統,也能夠隨機對目標用戶羣發一些調查問卷,肯定他們的實際使用狀況,以及安裝新版瀏覽器的可能性。

下下之策是查一下百度公佈的全網瀏覽器數據,而後說「咱們要支持某某瀏覽器,它還有 10% 市場佔有率呢!」,這是懶。

用戶帶寬

一樣是前端領域,文件的下載體積可能會被一些人當作亮點進行宣傳,可是你要清楚,如今已是 4G 時代了,更不用說不少企業內部應用都是千兆帶寬。就算能比候選技術小 100k,在 4G 帶寬下(假設現實帶寬是 2MB/s)也就是 100 毫秒,有誰能感受到這部分差別? 這就是一個明顯的「誤導讀者」的例子。

可訪問性

在產品的用戶羣體中,不但有健康人,還有色盲以及盲人等殘疾人。特別是對於面向消費者的產品,儘量的考慮這些人的需求不但能體現出產品的「人文關懷」,並且也在必定程度上擴大客戶羣。好比蘋果和微軟等大公司都把可訪問性放在了核心位置。若是你決定要實現可訪問性,那麼就應該把它做爲一項需求,歸入到選型時要考慮的因素中。

之因此要把它歸入到技術選型過程當中,是由於添加可訪問性支持的代價比較高,而不少第三方庫並無提供這方面的支持。因此應該提前考慮。

國際化

與可訪問性類似,國際化也是一個後期添加代價比較高,但不少候選技術卻沒有提供支持的特性。

若是你的產品在預期生命週期的至關一段時間內須要供多語言用戶使用,那麼,在初期選型時,就要把候選技術的國際化能力和質量歸入你的主要考量。

訪問頻度

用戶的訪問頻度對先後端的技術選型都有很大影響。

好比說一個一年只用一次的功能,考慮其性能極可能是沒有必要的,在一小時內跑完和在一分鐘內跑完每每沒有顯著的價值差別。可是這兩種技術方案卻可能有着硬盤佔用、編程複雜性、運維複雜性等方面的成本差別。你須要考慮:那種能在一分鐘內跑完的技術是否能給你帶來足夠的價值。

對於前端來講,頻繁訪問的、面向消費者的應用一般會要求更高的流暢度,那麼在技術選型時,就要選擇流暢度更高的技術。可是這個流暢度必定要設計一個仿真的場景,親自驗證一下,甚至作一些灰度發佈在現實場景下進行驗證,而不要只看其官網宣稱的流暢度。好比阿里的閒魚團隊就對 Flutter 技術進行了長時間的灰度驗證,最終替換成了徹底使用 Flutter 的版本,堪稱對新技術進行選型的模範。

用戶維度總結

要特別當心,不要根據錯誤的、片面的信息做出決策。不少第三方的技術選型指南背後都有着它們本身的場景,但大多數都不會給你寫清楚,有的甚至複雜到想給你寫清楚都作不到。甚至有些選型指南還有着強烈的主觀立場,爲了證實本身的預設立場甚至不惜造假。因此,你要先清點出大家的產品最應該重視的那些指標,而後拿這些指標對候選技術進行可行性測試,甚至爲此專門開啓一些 SPIKE 項目,而不要迷信第三方選型指南。

目標團隊

目標團隊的因素確實很重要,但並不像你認爲的那麼重要。除非你的人才供應真的有問題(難道不該該先反思一下是否是錢給少了?),不然應該優先考慮提高團隊能力,而不是削足適履。

技術背景

目標團隊的技術背景對新技術的選型確實很重要,可是不必去精確匹配。

好比 Java 團隊要作前端,選擇 GWT 看似很好,但 GWT 也有本身的問題,幾乎徹底沒法利用前端生態。他們更好的選擇多是 Angular:從語言上,TypeScript 跟 Java 有諸多類似之處;從架構模式上,對 MVC 的理解稍微往前推一步就是 Angular 的 MVVM 模式;從特性上,依賴注入不要太熟悉;從生態上,你能夠自由決定是否使用前端生態,取長補短。

一樣,前端團隊若是打算本身寫 BFF,也不必定非要在 Node 生態下打轉。你徹底可使用 Java 世界的 Reactor 或者 WebFlux 進行響應式編程。這樣能夠和後端的其它 Java 體系更好地進行集成,並減小運維的複雜度。

團隊規模

團隊規模多是團隊維度中對技術選型影響最大的因素。

四位開發人員如下的小規模團隊,若是你們都很專業,那麼其溝通成本就很低,在技術選型上能夠更傾向於選擇靈活的技術,由於較高的人員能力和較低的溝通成本,可讓靈活的框架更好地發揮其做用,最終更加高效、高質量的推出產品。這種場景一般出如今由牛人組成的創業團隊中。

若是開發人員經驗不足或者作事不夠專業,就須要更強的約束,特別是對於職場新鮮人,在早期養成好的開發習慣是很是重要的。而開發習慣中最重要的一點就是:約束 —— 知道不應作什麼。這時候,偏向自由的技術可能會一時爽,但最終會構築一個玻璃天花板,致使遲遲沒法突破到下一個層次。

若是團隊規模過大,那麼首要的選擇是用 DDD 等宏觀技術把問題域細分,使其能夠被小規模團隊承接。若是暫時還作不到,就要考慮建設完善的基礎設施和交付紀律,來爲團隊協做提供自動化保障。若是這些都作不到,就應該選擇強約束性的具體技術,讓你們避免犯錯,或者儘早發現錯誤。在爭取到時間以後,再逐漸深刻化解根本性緣由。

組織架構

康威定律深入地影響着不少方面,技術選型也不例外。特別是作宏觀技術選型時,必須考慮它在最終技術架構中的位置,以及與團隊溝通結構的匹配程度。即便是一項很先進的技術,假如它與體系中的其它技術棧不匹配,也可能致使翻車。

當選擇多個第三方庫的時候更要加倍當心,由於它們開發時互相不知道彼此的存在,特別是對於一些較新的技術,可能都沒人把它們搭配使用過。

除了開發架構以外,還要考慮更普遍的運維架構。假如大家引入了 DevOps,可能這個問題會獲得必定程度的緩解。假如沒有,那就要充分考慮上下游環節的人員能力和配套設施是否完備。好比若是運維部門缺少 NodeJS 運維技能,就不要盲目引入基於 NodeJS 的後端,必定要拿到他們「我能」的承諾以後再開始。

除非你是個先後端 + DevOps 全棧,不然就須要儘早對組織架構方面的因素進行驗證並排除風險。也就是說,在一個可控的演習環境中,用一個小型案例,完整地走一遍開發、上線、發新版的流程。在這個過程當中,一些顯著的風險將會暴露出來,要評估其影響,來決定如何選型。

人員流動性

人員流動帶來的損失比大多數人所認爲的要大得多。人員流動會帶走知識和文化。企業要避免損失,就要把這些知識和文化儘量記錄在代碼中。

固然,這並不意味着應該要求大量寫註釋,而應該使用那些能留存知識的技術,好比類型系統和規範化命名。類型系統和規範化命名能夠半強制性地要求開發人員把本來只存在於本身腦子裏的知識記錄到代碼中。若是更有追求一點,能夠再嘗試普及單元測試。這樣,當他離開的時候,即便沒有文檔,這些知識也仍然能留存下來。從效果上說,代碼每每比文檔和註釋更好。

而文化的留存則更加困難,事實上,代碼中的奇葩註釋每每留存的是負面文化。應該在代碼中留存的文化,是嚴謹、專業的工做態度。雖然自由也是文化的一部分,甚至在管理領域是很是值得嚮往的文化,但在工程領域,它每每是一種負面文化,由於軟件開發領域並無公認的法律甚至道德。你能夠想象一下管理領域中沒有約束的自由會致使怎樣的後果。

因此,要想應對人員流動的風險,除非你有信心留存知識與文化,不然就應該在技術選型時,傾向於選擇更加嚴謹的、隱式信息更少的技術。

團隊維度總結

鞋子好很差,只有腳知道。錯誤的選型,也只能由團隊自身來承受。阿波羅神廟上鐫刻着一句警世名言——瞭解你本身。因此,請先客觀認識本身的團隊,而後再據此進行選型,千萬不要懶於思考,盲從潮流。

技術自己

對技術自己的考量,主要是代入其它維度以後,看其匹配程度。

技術自己在選型中可能反而是最不重要的一個維度。這些年的歷史早已證實:優秀的技術未必能流行起來;不少技術的流行,也並不是是因爲其優秀。

明確的定位

一項優秀的技術,應該有其明確的定位和發展路線。這些定位能清楚地代表本身要作什麼、不作什麼。而其發展路線應該至少有一年以上的提早規劃,並且在定位上要能與其前輩作出有效區隔,而不是亦步亦趨,沒有本身的特長。

代碼質量

雖然流行的未必優秀,優秀的也未必流行,但技術選型不是趕時髦。因此,在條件容許的狀況下,仍是應該儘量選擇優秀的技術。代碼質量高的技術,未來技術自己因爲維護成本飆升而被放棄的可能性也較小。

衡量代碼質量的標準有不少,其中最經常使用、也比較有效的是單元測試的覆蓋率。而那些從一開始就具備比較完備的單元測試的代碼庫,每每優於後補測試的代碼庫。由於這證實的是開發組的工程化能力和意識,而這些是該技術長期可維護性的根本保障。固然,除非該技術特別複雜或應用場景的容錯性特別小,不然也沒必要苛求超過 90% 的覆蓋率。

維護團隊

維護團隊的規模和能力,對於一項技術在長跑中的表現很是重要。在歷史上如流星般劃過的技術數不勝數,但最終能長期留下來的卻很少。維護一項技術的成本遠高於建立它,因此若是沒有一個健康、可持續的商業模式,一個像 Linus 那樣的志願者,以及一個願意出錢的超級大金主,那麼它在將來的競爭中落敗只是早晚的事。除非這項技術的需求集足夠小而穩定,不然這些因素缺一不可。

社區

社區的質量,決定着這項技術長遠的將來,一些草根型技術的隱患就在於此。若是社區人員的素質太低,喜歡無原則的站隊,而不能理性的對該技術提出尖銳的意見甚至批評,那麼這個社區早晚會衰落。這類社區有一個顯著地特徵就是喜歡宣揚它「包治百病」,也就是說它適合一切場景,而不會先問你一些問題再決定是否要推薦給你。另外一個特徵就是喜歡經過刻意選取某些標準來作出片面的對比,這種行爲在學術界屬於學術造假行爲,但在咱們工業界卻被習覺得常,這不能不說是咱們的悲哀。

好的社區應該是一個君子社區。他們會自覺遵照共同的、理性的行爲規範。會把精力放在對技術自己作貢獻,而不是經過詭辯、羣毆等手段來攻擊競爭技術。社區的主要領導者會對社區的不良行爲提出批評、作出約束,甚至爲社區成員的不良行爲道歉,而不是聽任無論。

技術維度總結

不要把技術看得過重。對全部的主觀性宣傳文章,留一些心眼,多問一句——那缺點呢?未來決定大家是否會掉在坑裏的,就是它的缺點。

對於那些會如實告訴你缺點的宣傳文章,請高看一眼,由於做者是真的但願對大家團隊的將來負責。

對於功利社區,請務必當心;對於君子社區,請自覺維護。

反模式

有一些技術選型策略可能會致使災難性的失敗,這些選型中存在一些共同的反模式,好比:

輿論驅動選型

人云亦云,盲目聽信外人或者某些佈道師的主觀性言論,這就是輿論驅動選型。它每每會帶來災難。

作任何決策時,若是要藉助參考資料,請記住:最重要的不是它告訴了你什麼,而是它對你隱瞞了什麼,這些隱瞞的信息最終會置你於險境。

特別是當該資料的做者對某項技術具備顯著的傾向性時,請深刻想一想,他向你推薦的每一項優勢是否真的「對你」有價值,以及它背後的代價是什麼。好比,推崇「自由」的技術每每不夠「嚴謹」,若是你的產品須要嚴謹,那麼請把「自由」看作減分項而不是加分項。好比,推崇「體積小」的技術在如今動輒幾T硬盤、幾M帶寬的環境下,到底對你來講有多大價值?它是否是由於沒有其它的優勢了才把這種細枝末節亮出來吸引你?

即便是調查報告之類的客觀參考資料,也須要了解其背景。好比一份只發給程序員的調查報告,可能會發現 Chrome 的使用率超過了 99%,但顯然它對你的面向普通用戶的產品毫無價值,只會給你帶來風險。同時,要注意不少調查報告的設計是有主觀傾向性的,甚至題目的排列順序都會給最終結果帶來 10% 以上的誤差。因此,必定要仔細分析其中立性、客觀性以及調查對象在你的目標場景下的表明性。

單一指標驅動選型

根據任何一個單一指標進行選型都會給你帶來災難,更況且不少指標並不適合做爲選型的依據。

有些指標很容易操縱,好比 GitHub 倉庫上的 Star 就是很容易操縱的,在淘寶網上還有專門購買 GitHub Star 的服務,而 GitHub 的年度報告中也已經再也不把 Star 做爲主要指標使用。即便是那些不容易造假的指標,好比 commit 數量,其實也不適合做爲主要指標使用,它可能意味着做者具備良好的工程習慣和足夠勤奮,但也可能意味着代碼庫質量堪憂,所以不斷推出補丁。

固然,有一些客觀指標仍是比較適合做爲主要指標來使用的,但也不要盲目相信數字。好比單元測試中覆蓋率較高的項目,確實一般質量比較好,可是我也見過一些只有調用卻沒有斷言的測試,那些測試的覆蓋率也會很高,但倒是假的。因此,若是要評估其質量,最好仍是親自打開看一看。

即便你選出了一些主要指標,而且確信它們沒有造假,也仍然不能簡單地把它們加起來或加權平均來得出一個數字進行比較。你要綜合評估這些指標對你的目標產品、目標用戶、目標團隊的價值。若是技術選型只是個數字遊戲,那還要你幹嗎?

話語權驅動選型

這幾乎是最糟的選型,但卻家常便飯。技術棧的更迭每每會帶來話語權的變化,而這將給公司帶來災難。

對於高級技術決策者,須要有戰略定力,應該以一種規範的、用事實說話的方式來控制技術選型的反作用。我曾見過一幫程序員「偷襲珍珠港」致使架構師被迫辭職的慘劇,我當時的意見是:這是 CTO 的鍋。團隊因爲選擇技術棧而產生了話語權之爭,說明制度設計和文化建設出了大問題,這隻能由 CTO 背鍋。

因此,若是你是個技術決策者,那麼應該儘早站出來,發揮你的職權和非職權影響力,抑制這些負面文化,而不是任由其發展,最終破壞公司的整體技術路線,甚至技術氛圍。

粉絲驅動選型

對於生命線產品,最糟糕的選型莫過於粉絲驅動選型了,此次可沒有「幾乎」。對於技術人員來說,最重要的特質是客觀冷靜,這樣才能配得上「專業」二字。而拜大神,看成玩笑尚可,若是讓它影響到你的決策,那麼你就應該趁早隱退了,省得未來被迫引咎辭職。

雖然也曾被人稱做「大神」,但我通常會提出反對,至少不做正面迴應。我已工做二十多年,太清楚業界百態了。實際上,不多有人真的配得上大神的稱號,舉世可能只有 Anders Hejlsberg、Bob 大叔、Martin Fowler、Jeff Dean 等少數幾位。不過我相信若是你當面叫他們大神,他們也會反感的。

就算是對於這些舉世公認的大神,也不該該成爲你技術選型的依據,頂可能是相信他們會珍惜名譽、不會粗製濫造而已,由於即便是精品也仍然有着明確的適用範圍,超出這個範圍它也可能會成爲毒藥。

固然,對於邊緣產品,進行粉絲驅動選型也何嘗不可,甚至可能更好。只是得記住,要作就請作好,別給你的偶像丟臉,更不要作好以後就以爲公司必定要把它應用於生命線產品中。

決策樹

若是我在這篇文章的最後部分給你一棵決策樹,你會不會很高興?

很抱歉,寫這一章的目的,就是爲了告訴你:我不會給你任何決策樹。請根據我提供的思惟框架,自行設計適合大家本身的決策樹,及時更新它,而且不要盲目相信量化的評估結果。


文/ThoughtWorks汪志成

更多精彩洞見,請關注微信公衆號:ThoughtWorks洞見

相關文章
相關標籤/搜索