往事
2014年3月,Martin Fowler和James Lewis率先提出了微服務架構(gòu)這一武功秘籍,各路豪杰紛紛研習,一時大熱。然而不到一年,有人不得要領,有人走火入魔。Martin不得不再次出面,告誡人們要單體先行,切忌急功近利。不足七日,便有人在Martin的門戶中公然唱反調(diào),指責單體先行萬不可取。后有曾為微服務秘籍做注的Sam Newman不置可否地說,只待時機成熟,方可修煉。一時間眾說紛紜,江湖大亂。有詩為證:
分析企架皆模式,代碼重構(gòu)精益精。
縱橫軟件四十載,江湖人稱老馬丁。
一朝創(chuàng)立微服務,卻勸君單體先行。
莫問風雪何時了,你若歡喜便是晴。
新生
三體星上的和平愛好者對人類的忠告是:不要回答,不要回答,不要回答。
而人類面對軟件業(yè)諸多懸而未解的問題則是:無法回答,無法回答,無法回答。
時間永遠不會因為人類愚蠢的紛爭而停止她的腳步,轉(zhuǎn)眼間坐標來到了2019年。兩位分別來自英國和比利時的多才多藝的年輕人機緣巧合地聚在了一起。他們在前人特立獨行的思想基礎上,結(jié)合了認知心理學,提出了一個頗為大膽的假設:單體還是微服務并不重要,重要的是團隊的認知負載。
初看這一理論似乎并無太多新意,但細品之后簡直如醍醐灌頂。Martin Fowler和Sam Newman們無法用語言表達出來的模棱兩可,被如此輕描淡寫地化解。就仿佛一個置身四維空間的神,在低頭嘲笑三維空間中渺小的人類。這是一個徹徹底底的降維打擊。
不僅微服務架構(gòu)如是,你甚至可以就此發(fā)散開去:
- 敏捷開發(fā)取代瀑布式開發(fā)是為哪般??
- DevOps怎么會突然興起??
- 云計算為何如此火熱?為什么我們現(xiàn)在構(gòu)建的軟件都最好是云原生的??
你會發(fā)現(xiàn),團隊認知負載理論,或者說整個團隊拓撲學,并不僅僅是一個方法論,而是一個全新的世界觀。
什么是認知負載?
認知負載理論由認知心理學家John Sweller于1988年首次提出,它是指從事一件工作所要使用的腦力勞動的總和。Sweller在研究Problem Solving的時候發(fā)現(xiàn),不同的教學方式會對學習者產(chǎn)生不同的效果,造成不同效果的根本原因就是認知負載。
信息要想存儲在長期記憶中,就必須先被工作記憶(working memory)關注并處理。然而工作記憶的容量和持續(xù)時間都十分有限。在某些情況下,這些限制會阻礙學習進程,影響學習效果。沉重的認知負載會對學習產(chǎn)生負面影響。
Sweller將認知負載分為以下三類:
- 內(nèi)在(instrinsic)認知負載,是指與特定主題相關的腦力勞動。?
- 外在(extraneous)認知負載,是指向?qū)W習者呈現(xiàn)信息或任務的方式。?
- 相關(germane)認知負載,是指為創(chuàng)建永久的知識存儲而付出的努力。?
團隊認知負載與軟件開發(fā)
Matthew Skelton和Manuel Pais(剛才提到的那兩位“年輕人”)在他們提出的團隊拓撲學中,倡導團隊優(yōu)先的思維方式,以降低團隊認知負載為宗旨,避免工作內(nèi)容(架構(gòu)、運維等)超出團隊的最大認知負載。這樣,整個團隊就可以處于一個非常舒服的狀態(tài),去有效地應對軟件的復雜性,而不是疲于奔命。這種“以人為本”的思考方式,遠遠優(yōu)于單體或微服務那種只關注技術(shù)本身的視角。
Matthew和Manuel不但把認知負載的概念引入到了軟件開發(fā)領域,同時給出了他們對于不同分類的解讀。
- 內(nèi)在認知負載是指開發(fā)所需要的知識,如Java知識、前端知識等,也就是技術(shù)。?
- 外在認知負載是指如何部署、如何調(diào)試以及如何配置等,也就是機制。?
- 相關認知負載是指軟件要解決的問題,也就是與業(yè)務、領域相關的知識。?
其中,內(nèi)在認知負載是固定不變的,它是我們開發(fā)軟件所必備的知識;外在認知負載是需要盡量減少的,盡量避免與開發(fā)本身無關的腦力勞動;相關認知負載是要盡可能最大化的,因為這是我們在開發(fā)軟件時必須了解的業(yè)務知識。
為什么要盡可能減少外在認知負載呢?比如一個線上bug,修復它的內(nèi)在認知負載可能很低,只需要修改一行代碼。但我們在修復之前,搭環(huán)境、準備數(shù)據(jù)、調(diào)試、測試……可能一兩天的時間就這么過去了。這就是外在認知負載過高(環(huán)境不好搭、數(shù)據(jù)不好準備、不好調(diào)試、不好測試等)帶來的問題。
又比如每一個開發(fā)人員都遭受過的來自業(yè)務方或需求方的靈魂拷問:為什么這個需求這么簡單,卻要開發(fā)這么多天?其實需求看似簡單,但這里要改,那里要改,零零碎碎加起來就是需要好幾天。你可能也很委屈,但你是否想過哪里出了問題呢?為什么簡單的需求不能快速地上線?你也許會想到霰彈式修改,但這些都是表象。根本原因就是不合理的架構(gòu)和代碼結(jié)構(gòu),增加了團隊的外在認知負載。
唯一的答案
回到最開始的那些問題,你是否有了答案?
人們?yōu)槭裁床辉敢馊ヅ鰟虞m幾百頁的需求文檔,而更愿意閱讀只有一兩頁的故事卡?因為外在認知負載:以厚而全的文檔向人們呈現(xiàn)需求的方式,大大增加了外在認知負載。
人們?yōu)槭裁床辉敢馊ス芾黹L長的維護清單,而更喜歡基礎設施即代碼?因為外在認知負載:以代碼的形式來管理基礎設施,顯然要比手動運維具有更低的外在認知負載。
人們?yōu)槭裁床辉敢庾约嚎刂栖浖膹椥浴㈨g性,而更希望將軟件部署到云上?因為外在認知負載:把專業(yè)的事情交給專業(yè)的團隊去做,開發(fā)人員只專注業(yè)務代碼,將與己無關的外在認知負載拋在身后輕裝上陣。
從這個角度來看,單體微服務之爭是否顯得過于低級了呢?答案是如此顯而易見。你只需要評估一下什么樣的架構(gòu)更能減輕當前團隊的認知負載(確切地說是外在認知負載)就可以了。
軟件行業(yè)過往一切懸而未決的問題、似是而非的論斷,似乎都有了答案,唯一的答案。
是誰出的題這么的難?到處全都是正確答案。?