构建可信软件系统的 10 要素
(PS:此文不要太短)
(PS:此文花了幾個月寫的)
(PS:此文只是『版本 0.2』)
或許是軟件正在吞噬世界,或許是軟件不斷被重寫,越來越多的架構師、資深程序員開始關注起軟件質量。在最近的一兩年里,這種趨勢愈來愈加明顯,諸如于:
重構到領域驅動設計的架構
設計出演進式架構的系統
…… (編不下去了)
在這背后的主要原因是,我們為了更快的交付出軟件。一個代碼臃腫的后端單體系統,既不利于新人加入系統(他們會吐槽系統的復雜性),也不利于對系統的部分重構。而若是一個采用微服務架構的系統,每部分的代碼量都相當地小,能加快開發速度,也能快速方便的重寫。這讓我不禁聯想到之前同事說過的一個觀點:
為什么微服務成本很高,要將單體應用改成微服務?
為什么中臺并不能解決問題,但是還是要做中臺?
為什么微前端不是銀彈,但是我們仍然想做微服務?
……
『因為代碼寫得爛吧,質量上不去,自然需要找個好的理由來重寫應用』。舊的代碼不好維護,只是其中的一個理由。現在,加上了新的技術、新的架構,已然變成了兩個理由了,也就是一個好的理由。
引子 1:代碼到架構的腐爛
架構的腐爛來自于代碼的壞味道,而代碼的壞味道則是屬于技術債務,于是乎技術債務的無力償還才是代碼質量背后的問題。這里的技術債務,指的是為了快速解決問題而采取的不規范方案?[tech_debt]。而如《軟件設計重構》一書所提及的,這些相關的技術債務有:
[tech_debt]: https://www.infoq.cn/article/xgP9W*MC6Svi9Zcqd5KX
代碼債務:代碼風格不一致、靜態分析的違規
設計債務:設計壞味道、違反設計原則
測試債務:測試不充分、測試設計不合理
文檔債務:缺少文檔、文檔糟糕及文檔過期
時間太短
能力不夠
不重視技術,不去設計及優化
順帶一提,在《前端架構:從入門到微前端》一書中,處理技術債務的部分是在項目周期的最后一部分『成長優化期:技術債務與演進』。雖然不愿意這么說,但是你可以延期技術債務,但是一旦要去解決它。
所以呢,對于這種系統來說,推翻還是維護、重寫還是重構就成了另外一個問題。
引子 2:基于架構金字塔的軟件架構
架構是體現在它的組件中的一個系統的基本組織、它們彼此的關系、與環境的關系及指導它的設計和發展的原則。—— IEEE (1471 2000)
所以,在《前端架構:從入門到微前端》一書中,我們提出了設計架構時所需要的層次要素,便有了架構金字塔。
架構層級為此,我們劃定了架構的四個層級 + 基礎設施層:
系統級,即整個系統內各部分的關系,諸如于如何通訊,以及如何與第三方系統如何集成等。
應用級,即單個應用的整體架構,及其與系統內單個應用的關系等。
模塊級,即應用內部的模塊架構,如代碼的模塊化、數據和狀態的管理等。
代碼級,即從代碼級別保障架構實施。
注:圖中的服務導向架構出自于《演進式架構》,包含了 SOA、微服務架構及基于服務的架構等;而聚合導向架構指的則是客戶端的架構模式,客戶端以聚合來展示一致性,諸如前端領域的微前端、移動應用的插件化等。
這種架構模式,特定符合我們日常設計架構的特點:先自頂向下設計,再自底向上實踐(適應)。
先自頂向下設計
架構的設計模式,讓人不禁聯想到設計領域里 Design System 之中的 Atomic Design。原子設計是一個設計方法論,由五種不同的階段組合,它們協同工作,以創建一個有層次、計劃性的方式來界面系統。
Atmoic(PS:順帶一提,在用戶體驗這一領域,人們提出了一個新的概念叫 DesignOps,其目的在于告訴人們,設計是一個可持續的過程。只是 Ops 這個詞用的真的沒那么好)。
相似的,我們將其中的生物模型與我們的金字塔架構做一層映射,就得到了我們所需要的架構層次模型:
原子級 <-> 代碼
分子級 <-> 模塊/組件
組織級 <-> 應用
有機體 <-> 系統
對應于中大型企業,便是公司 - 部門 - 組織 - 個人,這令人討厭的金字塔層次結構。
不過呢,系統設計難的部分并不是這部分的設計,因為道理我們都懂。(PS:所以我在這里刪去了幾百字相關的解釋部分,手疼寫不動了)。
只是呢,順便一帶,這里的組織級是一個非常好的概念,它能讓我們在滿足康威定律的同時,適配出更好的架構模式。當我們構建可演進式系統時,每一個組織級部分的服務、應用都要能變成可犧牲式服務。
對于架構的設計來說,最難的地方在于自底向上去適應、成長。
再自底向上適應
當我們劃定了四層架構之后,我們會發現大部分軟件系統的設計有出現一定的問題——只設計了頂層架構,缺少了代碼級別(原子級別)的基礎適應度函數的設計。(PS:對于小型 IT 團隊來說,它們還缺乏基礎設施。)
即,為了保護整個系統的架構不被破壞,我們還需要:
測試覆蓋率。
進行架構守護。
代碼整潔規范。
設計原則與設計模式。注意,這里的設計模式,并非單單指 23 種設計模式,而是模式的總稱。
blablablablablala
而這些東西被總稱為『適應度函數』 (《演進式架構》 ,這幾個字高度降低我了我的解釋煩惱——只要能幫助系統持續性變好,就可以稱之為適應度函數。
不過,從生物學 + 科技 => 遺傳算法的角度來解釋:
適應度函數是一種特定類型的目標函數,用于總結作為單個品質因數的給定設計解決方案與實現設定目標的接近程度。適應度函數用于遺傳編程和遺傳算法,以指導模擬向最優設計解決方案。—— 維基百科
引子 3:軟件的構建流程
當我嘗試去尋找一個適合的軟件流程圖,我發現現有的流程也都不對——它們就像是科班研究人員畫出來的,缺少一些輔助的技術實踐。而這些實踐可以幫助我們更好地構建系統,并開發出符合當前模式的架構。
所以,我嘗試創建一個更完整版本的軟件流程圖,以幫助大家理解文章的剩余部分。
可信任系統流程受限于篇幅原因,我并不打算在這篇文章詳細解釋上圖(手疼,下次補上,雖然不知道什么時候),大家就意會、意會、意會吧。
不過,我這個版本還只是 0.1,所以仍然有大量的東西需要改進。畢竟,此圖不是我們的重點所在。對了,畫圖的工具是 iPad + OneNote,結合 MBP + 公司提供的正版 Adobe Photoshop CC 2019(我沒收廣告費,它們不給)。
終于,我們要結束了?(沒錯,湊點字數)。
不,這才開始要進入正題。
1. 清晰可見的架構遠景
架構遠景目的是闡明一種架構愿景,以實現業務目標,響應戰略驅動因素,遵守原則并解決利益相關者的關注和目標。—— OpenGroup.
架構遠景相當于是企業在技術上的宗旨/文化,用于幫助公司人員更好地了解公司整體的技術架構方向。除此,我們還需要知道的是架構遠景,類似于組織文化,長和短都不合適。
架構設計原則
不同的人在設計架構的時候,會出現不同的風格。在細節的把握上,也會出現特有的風格,這便是架構的設計原則。——《前端架構》
對于一個組織來說,組織會出現固有的模式(pattern),這種模式會出現在代碼的風格上,諸如于它們對于安全的要求、對于系統穩定性的追求等等。這些特征會在代碼實現的時候一一體現出來。所以,既然我們需要展現這些架構原則,那么直接明確出來,會變得更為簡單。
如我在設計系統的時候,也會有一些偏好:
不多也不少:即不做多余的設計,也不缺少關鍵部分的設計。
演進式:不斷讓架構適應當前的環境。
持續性:長期的架構改進,比什么都重要。
PS:對于中大型 IT 團隊來說,有這樣的原則更容易傳遞信息。對于小的 IT 團隊來說,它取決于技術負責人的風格,也不適合確定下來 —— 因為業務可能隨時會變化,技術的方向也可能隨之變化。
架構的多層級可視化
在眾多的架構模型中,如 TOGAF、4 + 1 視圖等,我最喜歡的是 C4 模型。因為它是一種可以真正反應系統架構的架構表達方式。
C4 代表上下文(Context)、容器(Container)、組件(Component)和代碼(Code)——一系列分層的圖表,可以用這些圖表來描述不同縮放級別的軟件架構,每種圖表都適用于不同的受眾。—— Simon Brown 《程序員必讀之軟件架構》
換句話來說,C4 模型適用于軟件開發團隊的各個 level 的成員——架構師、Tech Lead、開發人員、新成員等。也因此,C4 可以直接反應系統的架構原則 ,并能直觀地幫助項目的新成員熟悉項目。
陷阱 1:光有架構遠景,缺少原則與實踐指南。
最佳實踐 1 :物理可視化 C4 模型。
2. 高度自動化的工作流
工作流(Workflow),是對工作流程及其各操作步驟之間業務規則的抽象、概括描述。
作為一個程序員,我們除了不喜歡寫文檔,我們還不喜歡看別人寫的文檔。
開發工作流可視化
在每一家中大型公司里,都有『數不盡』的流程,它們也采用了工作流引擎來完成這部分工作的數字化。但是就我個人而言,物理化的方式才能幫助每個人熟悉流程。
最佳實踐 2:物理可視化 Path to Production。
有興趣的同學,可以閱讀上述的文章,這里就不詳細展開了。
開發工作流自動化
對于一個技術先進的組織來說,一個新的項目成員來到這個項目時:
ta 的開發機器應該能執行一個或者多個腳本,便能完成開發系統的初始化。
ta 的開發環境應該能執行一個或者多個腳本,便能完成開發環境的設備。
ta 的開發環境應該能執行一個或者多個腳本,便能運行起來。
ta 的代碼提交到版本管理服務器時,便能完成自動部署到測試環境。
如果做不到自動化,那么就可視化。
風格受限的規范實踐
除此,在這些工作流中,我們還會穿插一些代碼規范:
提交 Hooks,諸如于 prepush 或者是 precommit 等
代碼風格自動審查(Lint)。
函數式的規范化。
提交信息格式。
命名規范。
由于,這里就不詳細展開了。
注:命名規范參考。如在后端開發中使用的《后端開發實踐系列之一 —— Spring Boot項目模板》中介紹的一些模式:
客戶端的請求數據類統一使用相同后綴,比如 Command
返回給客戶端的數據統一使用相同后綴,比如 Represetation
對應于前端來說,對應的可能是:
請求服務端使用相同后綴,如 Request
處理返回端返回的結果,如 Response
時間表(可選)
從個人的角度來看,一個時間表有限于輔助實施各種實踐。不過,有的人并不喜歡這種方式。
最佳實踐 4:特定時間特定活動。它是一個非常 SMART 的目標。
當你決定 code review 時,你需要 5:00,那么在制定會議的時候,考慮這個因素。如果是周五,那么可以在周五改成 4:30,或者不執行。
當你決定站會時,那么 9:20 可能是你的最好時間,不固定的話就不要。
當你決定 blabla 時,那么決定好你的時間。
但是當你們容易忘記事情的時候,這就是一個不錯的選擇了。
3. 設計架構適應度
軟件架構的復雜與業務系統的復雜度成正相關,復雜的業務系統其架構自然也就復雜了,簡單的業務系統其架構也相對地就簡單了。不過,多數地軟件系統都是隨著業務地發展,而慢慢變得復雜。這種情況下,架構只能不斷去演進。
所以,對于多數系統的架構來說,最初的設計者并不存在問題,他/她們都是根據當時的情況,做出合理的選擇。往往是過程中的開發者,對于架構不加思考地延用導致的。
于是乎為了設計出《演進式架構》,我們需要設計出多個適應度函數,以幫助系統不斷地演進。而軟件架構本身是多層次的,對應的架構適應度函數也是對應于不同的層次。
多層次適應度函數
對應于我們的四個層級,便有了一些常見的適應度函數 - 架構的映射:
應用 / 監控級:架構守護測試、架構衡量指標、集成測試、監控、契約測試
模塊級:組件測試、集成測試
代碼級:單元測試、代碼質量指標、
除此,還有不屬于架構金字塔的各種指標,這里就不詳細展開了。(PS:對,去讀讀那本書就可以了。)
陷阱 2 :適應度函數一次性過度。一旦發現了合適的適應度函數模式,比如參考其它公司的適應度函數,那么我們應當一一進行。
4. 完善工具與基礎設施
適合的工具與基礎設施,能極大地提升系統的開發效率。也是軟件體系開發中非常重要的一環。
對于小型 IT 團隊來說,選擇適合的工具和基礎設施,是一件非常困難的事情。它受限于團隊的經驗和能力,以及其在市場上很能招聘到的新成員。
對于大型 IT 團隊來說,開發適用于組織的開發工具、基礎設施都是一筆非常劃算的買賣。
4.1 構建基礎設施
團隊在不斷發展地過程中,會積累出大量的經驗。這些經驗可以變成組織內部的基礎設施(它也可以是由外部演化而來的)。常見的一些基礎設施有:
API。
模式庫。Lombok、Ramda 這一類工具庫,Spring、Angular 實際上也是模式庫
云平臺 / 云原生平臺。
設計系統 & DesignOps。
最佳實踐 5:開發大型組織的 API 市場。對于大型組織來說,部門間的競爭可能會較為激烈。不過,開發一個減少重復工作的 API 市場,即能幫助團隊減少開發量,還能幫助其它團隊快速的開發應用。
4.2 生產力工具
我喜歡使用 Intellij IDEA,它用途廣泛。通過熟悉其提供的各種功能、快捷鍵,極快地幫助我開發系統。當你熟悉了一個工具之后,切換另外一個工具成本就變高了。而 Eclipse 和 VS Code 也是非常不錯的工具,他們的開源模式及插件能力,已經被驗證過。而小程序采用的 Electron,也被證明是一個非常不錯的系統。
當然了我喜歡的 Emacs 或者是 Vim,就是定制麻煩一些。
陷阱 3 :?全局統一而非系統多樣性。統一的工具如 Intellij iDEA 可以幫助組織、團隊更好地使用工具,但是不禁止多樣性能吸納更多的人才。一定范圍內的最優,促能進系統演進。讓開發人員日常討論也是非常好的(畢竟,PHP 是最好的語言。)
陷阱 4 :?過度多樣化導致失控。這是另外一個極端的反例,如果組織內部出現大量的不同技術設施,就無助于整體提升。為此,一些常見的方式便是限制使用某幾個工具。
5. 高效的測試策略
在先前的文章里,我們花了大量的時間在測試這個話題上。盡管測試仍然是國內公司的一個心頭痛,但是隨著對于質量要求的提高,這個話題也會越來越多的被提及。
對于測試來說,有兩點還需要再補充一下:
需要贏得公司內部上下的支持。一個常見的說服點是,保證質量——如果公司對于軟件質量要求不高的話,那么這一點就站不出腳了。
讓大家能寫測試是比較難的部分。
對應的一個最佳實踐:伴隨業務開發的、遞增式測試覆蓋率提升。如我在那篇《項目初期的最優技術實踐》所說,測試往往是伴隨在業務功能的開發之后完善的。
為此,還有一個簡單的測試策略:
公用的 utils、helper 函數是必須測試的
公用的組件是必須測試的
執行速度快的單元測試越多越好
happy path (無異常情況時)是需要測試的
E2E 測試用于測試核心的業務邏輯(速度慢)
當測試執行的時間長, 影響到開發時,可以在持續集成上分離出測試專用的 pipeline。
陷阱 5 :KPI 式測試覆蓋率。特別是無效斷言的測試——調用了相關的函數,最后 assertEquals(1, 1);
陷阱 6 :過度的 E2E 測試。減緩系統開發。為此,我們需要分離 E2E 測試,降低非關鍵性測試 —— 如 About Me 測試。
6. 更好的知識傳遞
知識傳遞,是指以交流和繼承認識成果,取得間接經驗的一種教育形式。
在設計架構和系統的時候,我們務必要考慮其在整個系統中的實施。畢竟知識傳遞的速度,是限制一家公司發展的關鍵因素之一。。在日常的軟件開發中,常見的知識傳遞的方式有:
文檔。
代碼檢視。
日常站會。
結對編程。
測試用例。好的測試用例可以直接體現業務邏輯,而不需要多余的解釋。
我們最常遭遇的一個是陷阱 7 :不及時更新、滯后、無效的文檔。
6.1 文檔代碼化
常見的文檔代碼化方式主要是:
項目的 README。
項目的架構文檔等。
架構決策記錄。架構決策記錄,是一個類似于亞歷山大模式(即:設計模式)的短文本文件,(雖然決策本身不一定是模式,但它們分享著力量的特征平衡。)更多的內容可以參考:【譯文】架構決策記錄(Architecture Decision Records)。
項目發布文檔
其它相關的 wiki
順便一題,如我司大佬滕云在 《后端開發實踐系列之一 —— Spring Boot項目模板》 所說一個合理的 README 應該包含:項目簡介、技術選型、本地構建、領域模型、測試策略、技術架構、部署架構、外部依賴、環境信息、編碼實踐、FAQ 等。
這就有一個問題,文檔更新的 KPI 算在哪里?在諸如 Tech Lead 文化的公司里,這是由 TL 必須做或者委派的事情。所以這就涉及到一個文檔的 Ownership 問題。
陷阱 8 :采取無法版本化的文檔,諸如于 word、excel 等二進制文檔。
6.2 組織內部分享知識
我們很高興地看到,越來越多的組織在內部鼓勵技術知識的分享,這是一個非常好的舉措。雖然在一些組織里已經變成了一種 KPI。盡管如此,它所帶來的益處遠遠大于它的負面作用。
6.3 不止于代碼的代碼檢視
陷阱 9 :不規范的儀式化代碼檢視。敏捷站會的三句話,昨天做什么,遇到什么問題,今天做什么,它有著容易記住和實施的特點。代碼檢視也有相似的做法,實現什么功能(業務),遇到什么問題(技術),接下來怎么做。
代碼檢視(Code Review)是一個非常有效的知識方式,比它更有效的恐怕就是結對編程了。但是,人們一直忽略了代碼檢視的一個重要內涵,知識傳遞。如果你在代碼檢視(Code Review)的時候,有任何上下文相關的業務問題、技術問題,那么你應該提出來,而其它團隊成員也應該幫你解決這個問題。
7. 框架與模塊的與時俱進
首先,我的意思并不是說,使用最新的技術。而是,不再維護舊技術債下的代碼……。當你使用的是一個古老的技術債,那么在市面上很難找到對應的人來維護系統,那么早晚你也會拋棄掉這們技術的。
1. 主框架的更新節奏
在我們日常的開發習慣中,最容易出現的一個問題是:往往在創建項目之后,依賴就很少被更新了。因為,我們一直擔心更新框架的版本,會影響系統的其它部分。
也就有了陷阱 10 :懼怕破壞性變更。一旦你的應用因為框架的更新,而不斷地需要全局修改,那么說明架構不合理 ——?應用與框架綁定過度。一旦發生了這種事情 ,我們就需要知道為什么。為了適配 API 的變化,需要的是裝飾者模式,或者適配層。
所以,在這種情況下,便會產生依賴的破窗效應。一旦某個依賴出現某種破壞性的 API 變更,沒有人愿意去更新時,這個依賴便會發生破窗效應 —— 如果那些窗不被修理好,可能將會有破壞者破壞更多的窗戶。換句話來說,就會有越來越多的依賴不被更新。
2. 時時更新輔助依賴
是的,對于那些輔助開發的依賴,可以使用工具來保持時時更新。
陷阱 11 :熱鬧驅動開發 / 簡歷驅動開發。這是最常見的一個陷阱,出于熱門的原因,使用最新的工具和框架。
8. 邊界限定的系統架構
過去,我們采用模塊化來劃定包之間依賴關系;現在采用的是微服務化取代了部分內部包依賴。即以 HTTP 請求代替來函數調用。
所以,我們將巨型單體應用(陷阱 11 )視為一種毒瘤,順帶強調一下巨型!巨型!巨型!
而與之恰恰相反的是 :?過度解耦(陷阱 12)。這是最常見的一個錯誤,微服務并非越多越好。我們犯過的一個錯誤是,項目的微服務比項目的成員多,比如說 8 個成員 12 個微服務(按 A-Z 編排)。這樣一來,每個成員承擔著多個微服務的重任,在基礎不完善的組織里,它意味著每個成員要上線并測試多個服務。
8.1 組合優于復合
諸如于服務導向架構中的微服務模式,往往會采用 BFF(Backend for Frontend) 來。對于后端而言,使用 BFF 而不是單一服務提供具體業務,能極大提升 API 地純粹性。對于客戶端而言,多個功能相近的組件,比一個負責的組件更易于維護。
舉個例子,對于采用 BFF 架構的系統來說,每一個客戶端都會有一個單獨的 BFF 服務。比如說,iOS 是一個 iOS BFF,Web 是一個單獨的 Web BFF。而往往為了實踐方便,這些 BFF 都是同一個 BFF。而一旦不同類型的客戶端差異比較大時,獨立出不同的 BFF 并是一個勢在必行的選項。嗯,組合而不是重復。
8.2 適配層,而非被接口適配
軟件的適配層,這個已經是一個耳熟能詳的話題。
然而,我們仍然可以看到在諸多的團隊里,它們仍然采用的是依賴于接口的 API 設計方式。諸如于直接轉發第三方接口,一旦第三方接口發生變化 ,那么我們的調用方也需要跟著發生變化。
8.3 分層架構的二次分層
事實上,不論我們做出怎樣的架構決策,在當前的技術?『樹型目錄結構』決定了落地架構必是『分層架構』。過去我們采用的往往是技術分層的方式,而當項目過于龐大時,那么就可以采用業務 +技術分層的方式:
domain -?services -?controller -?infrastructure -?……即 Martin Folwer 在《Presentation Domain Data Layering》一文中所提及的水平 + 垂直拆分的方式。
8.4 劃分邊界
事件風暴(Event Stroming)是一項團隊活動,旨在通過領域事件識別出聚合根,進而劃分微服務的限界上下文。
今天,全景事件風暴已經被證明是一個非常有效的劃分限界上下文的方式。
拆分成多個微服務,并維護多個微服務不是一個愉快的過程。但是我們可以采用『應用微化架構:構建時拆分』 模式,即:一份代碼中,構建出適用于不同環境的多套目標代碼。
9. 持續償還的技術債務
你已經看來了,我們把重要的話題,放在文檔的后面。技術債務就是這么一個重要的話題。大部分的系統變成了遺留系統,實際上也就是因為積累了越來越的技術債務,導致最后無法維護。
9.0 技術債務頭腦風暴
是的,進行一場技術債務相關的頭腦風暴,能讓我們明確列出大部分的技術債務。
這些常見的技術債有:前期設計不足、業務壓力導致的快速發布、延遲的重構、過度耦合的組件、缺乏文檔、缺少測試等等。
9.1 可視化技術債務
處理技術債務的第一步,也就是最重要的一步,可視化技術債務。而管理技術債務的方式和管理看板的方式相差無幾:
明確優先級
使用 TODO、Doing、Done 的涌道管理
明確責任人
給定時間范圍
……
作為一個 Tech Lead,如果你每天上班看到的就是技術債務,那么你就會想辦法去解決——不過,你知道的,技術債務和業務一樣,都存在優先級。高價值且容易實現的,應該優先去做。
陷阱 12 :只可視化而不實踐。數字化很棒,但是你更需要的是實踐。以我的項目經驗來看,通過物理板可視化更為有效,天天就會看到。
9.2 驅動技術債務的償還
大廈將傾,一木難支。
一旦技術債務越來越多,真正的行動也就勢在必行。畢竟『安有巢毀,而卵不破乎』。
陷阱 13 :業務完全讓位于技術。技術需要用于證明業務價值——除非,系統真的不得不重寫,我們才有必要完全鋪在技術重構上。否則,我們應該平衡技術與業務,然后做出適當的妥協。
10. 強有力的個人 & 愿意改進的團隊
(手疼 + 沒啥說的 + 補充一點額外話)
強有力的個人指的是團隊內技術被大家認可的人,并且它能帶動團隊前進——兩個條件缺一不可。在 ThoughtWorks 中的 Tech Lead 便是強有力的個人,而并非 Tech Manager / Project Manager。
對于團隊來說,『資深』程序員過多,不想獲得改進,會導致越來越改進。所以,一個~~有待商榷的~~改進措施是,促進組織內人員的多樣性。團隊的多樣性受到影響時,那么團隊開始有不好的趨勢。
結論
天上不會掉下銀彈的——沒有銀彈。
黃峰達(Phodal)是一個咨詢師、極客、創作者和作者,現作為一個資深咨詢師為 ThoughtWorks 工作,他喜歡在現實世界和虛擬世界中創造和分享。
他喜歡分享軟件開發經驗,以幫助開發人員構建更好的軟件系統。他撰寫了三本關于軟件開發的書籍,分別是《前端架構:從入門到微前端》、《自己動手設計物聯網》、《全棧應用開發:精益實踐》。他還是七本有關物聯網和前端開發的書籍的技術審閱者。他是一位開源愛好者。他在 GitHub 中創建了許多實用的開源軟件。此外,在日常工作之后,他喜歡重新發明一些輪子以獲得樂趣。你可以在他的GitHub 頁面上找到更多的輪子。總結
以上是生活随笔為你收集整理的构建可信软件系统的 10 要素的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海量电子书下载
- 下一篇: Nepnep战队:哪有什么一战成名,其实