0.引言
在互聯網行業(yè),軟件工程師面對的產品需求大都是以具象的現實世界事物概念來描述的,遵循的是人類世界的自然語言,而軟件世界里通行的則是機器語言,兩者間跨度太大,需要一座橋梁來聯通,抽象建模便是打造這座橋梁的關鍵。基于抽象建模,不斷地去粗取精,從現實世界到業(yè)務模型,從業(yè)務模型到設計模型,最終完成現實世界到軟件世界的轉換。
事實上,服務端開發(fā)工程師在大部分工作時間里并不是在寫代碼,而是在抽象建模。工程師需將業(yè)務需求抽象成領域模型、模塊、服務和系統,面向對象開發(fā)時需抽象出類和對象,面向過程開發(fā)時抽象出方法和函數。
某種意義上,軟件的本質就是抽象,建模則是系統地實施抽象的過程。作為一種將事物形象化的有效手段,建??蓪F實世界中的事物及事物之間的關系準確地表達出來。
1.抽象思維
抽象在中文里可作為動詞,也可作為名詞。作為動詞的抽象是指一種行為,這種行為的結果,就是作為名詞的抽象。百度百科對抽象的定義為:人們在實踐的基礎上,對于豐富的感性材料通過去粗取精、去偽存真、由此及彼、由表及里的加工制作,形成概念、判斷、推理等思維形式,以反映事物的本質和規(guī)律的方法。
事實上,抽象作為一種高級思維形式,與日常生活關系密切,例如數字,人類初期并沒有數字這一概念,原始人類或許能夠理解三個蘋果和三只鴨子,但不存在數字 “三” 這個概念,在他們的意識里,三個蘋果和三只鴨子是沒有任何聯系的。當人類文明發(fā)展到一定階段,發(fā)現了這兩者之間存在的一種共性,即 “三”,于是就逐漸形成了數字這個概念。此后,人們就開始用數字對各類事物進行計數。
2.軟件世界中的抽象
軟件的本質就是抽象,在軟件世界里,抽象無處不在,典型如命名抽象、分層抽象、原則抽象。
2.1 命名抽象
作為一名軟件工程師,最令你頭疼的事情是什么呢?是寫代碼,看別人的代碼,需求評審,還是修 Bug?Quora 和 Ubuntu Forum 曾經針對這個問題進行過廣泛地調研,結果顯示,?最令軟件工程師頭疼的事情是命名,沒錯,就是命名!應用名、包名、類名、方法名、字段名、變量名等等。如果你不曾為命名苦思冥想、反復權衡,也許你還不能算是真正的軟件工程師。
關于命名,Stack Overflow 的創(chuàng)始人 Joel Spolsky 曾言:“起一個好名字很難,但這是理所應當的,因為一個好名字需要把要義濃縮在一到兩個詞(Creating good names is hard, but it should be hard, because a great name captures essential meaning in just one or two words)?!?其實,這個濃縮的過程便是抽象的過程。
很多時候,業(yè)務代碼的復雜,并非業(yè)務本身復雜,而是人為因素造成的,命名混亂就是最常見的因素。雖然不合理的命名并不影響需求的實現,但卻加重了認知負荷,隨著時間的推移,理解代碼的成本會越來越高。同時,命名不合理本質上是抽象不合理,往往影響可復用性。
2.2 分層抽象
在軟件開發(fā)中,經常會用到各種分層架構,如經典的三層模型(展現層、業(yè)務邏輯層、數據層)和 MVC (Model、View、Controller)模型。如圖 1 所示為阿里廣泛采用四層模型,它包括 View、Service、Manager、DAO 四部分,通過分層將數據訪問、通用處理、業(yè)務邏輯、終端展示四者解耦,各司其職。View 與用戶交互;Service 依賴多個 Manager 和 DAO 實現具體的業(yè)務邏輯;Manager 負責通用業(yè)務邏輯處理和封裝外部服務,它是對 Service 層通用能力的下沉,注重復用性;DAO 負責與底層數據庫進行數據交互。分層架構的核心其實就是抽象的分層,每一層的抽象只需要而且只能關注本層相關的信息,從而簡化整個系統的設計。
圖 1 四層模型?
2.3 原則抽象
在面向對象設計和面向對象編程領域,有一個著名的 SOLID(單一功能、開閉原則、里氏替換、接口隔離以及依賴反轉)原則,它是由 Robert Martin 在 21 世紀早期提出。在軟件設計和開發(fā)中,正確地遵循這些設計原則,有助于提升系統的可維護性和可擴展性。
以依賴倒置原則(Dependency Inversion Principle, DIP)為例,其含義為:抽象不應該依賴于細節(jié),細節(jié)應當依賴于抽象。換言之,要針對抽象(接口)編程,而不是針對實現細節(jié)編程。這樣做有什么好處呢?一個軟件系統通常可劃分為多個層次,上層調用下層,上層依賴于下層,如果上層依賴的是下層的具體實現,那么,當下層實現細節(jié)發(fā)生變化時,上層往往也需要同步修改,這就加重了不同層之間的耦合度。但是,如果上層依賴的只是下層的抽象而不是細節(jié),就完全不同了,抽象變化的頻率極低,讓上層依賴于抽象,實現細節(jié)也依賴于抽象,即使實現細節(jié)不斷變動,只要抽象不變,上層就不需要變化,如此一來大大降低了耦合度。
Java 的 JDBC 是依賴倒置原則的一個典型應用場景 。如圖 2 所示,如果沒有 JDBC 這一層抽象,軟件系統將直接依賴具體的數據庫(如 MySQL、Oracle 等),與實現細節(jié)耦合,當需要切換到另一種數據庫時,就需要修改大量代碼來適應細節(jié)的變化。若系統依賴的是抽象的 JDBC 接口,那么通過調用 JDBC 即可完成數據庫操作,而無須再關注 JDBC 背后的數據庫,因為所有關系型數據庫的連接庫都實現了 JDBC 接口,當需要換數據庫時,作為抽象的 JDBC 并不會變化,系統也就無需感知變化。
圖 2 依賴倒置原則典型應用場景?
3. 經典抽象案例
如圖 3 所示,有這樣一個關于 “霸屏” 動效的需求,產品文檔(Product Requirement Document,PRD)摘要描述如下:
-
ZFB 會員與 KA(Key Account) 商家合作,升級會員等級特權,因此在會員頻道首頁通過 “霸屏” 動效提示用戶并引導其進入新等級特權頁面;
-
若用戶點擊 “看我等級特權” 按鈕,則自動跳轉到新等級特權頁面,引導目標達成,“霸屏” 動效不再出現,以免打擾用戶;
-
若用戶未點擊 “看我等級特權” 按鈕,“霸屏” 動效展示 3 秒自動收起。由于引導目標未達成,需繼續(xù)引導,同時為了防止過度打擾用戶,“霸屏” 動效每月最多出現 N 次,N 需支持靈活配置。
圖 3 等級特權引導“霸屏”視覺效果?
我們來簡單分析一下這個需求,核心業(yè)務目標在于引導用戶進入新等級特權頁面,同時兼顧用戶體驗,避免 “霸屏” 動效過度打擾用戶。對于服務端而言,需要實現 “疲勞度” 控制邏輯,即:
-
若用戶點擊按鈕:持久化用戶點擊記錄,當用戶再次訪問該頁面時,通過查詢點擊記錄就可以判斷該用戶是否曾點擊按鈕。若記錄存在,則告知前端不要彈出 “霸屏” 動效。
-
若用戶未點擊按鈕:持久化 “霸屏” 動效對用戶的曝光記錄,當用戶再次訪問該頁面時,通過查詢曝光記錄就可以判斷該用戶是否滿足展示 “霸屏” 動效的條件。若當月曝光次數少于 N,則告知前端可彈出 “霸屏” 動效。
3.1 方案一:戰(zhàn)術抽象,多快好省,跑步前進
基于上面的需求分析,稍有經驗的服務端開發(fā)工程師立馬就能想出解決方案,如表 1 所示,為每個用戶落一條記錄即可實現需求。
表 1:點擊、曝光記錄模型概要?
?從實現需求的角度來看,上述設計完全可以滿足業(yè)務當前的需要。如圖 4 所示,曝光、點擊記錄模型幾乎完全是由產品文檔(PRD)翻譯而來,乍看之下,十分的 “信達雅”,簡直不要太完美。
圖 4 將 PRD 翻譯為模型?
我們再來仔細分析一下,上面的模型真的好么???顯然很一般?。?!該模型局限于實現當前業(yè)務需求,幾乎沒有進行抽象建模,因此,建立的模型不能準確地刻畫業(yè)務的本質。這樣的模型可擴展性極差,基本就是一錘子買賣。
在筆者看來,直接 “翻譯” PRD 是一種戰(zhàn)術編程,或者說戰(zhàn)術抽象。John Ousterhout 在《A Philosophy of Software Design》一書中提到:幾乎每個軟件開發(fā)組織都至少有一個將戰(zhàn)術編程發(fā)揮到極致的開發(fā)人員,可稱之為戰(zhàn)術龍卷風(Almost every software development organization has at least one developer who takes tactical programming to the extreme: a tactical tornado)。戰(zhàn)術龍卷風有以下幾個特點。
-
快速。他們常以腐化系統為代價換取當前最快速的解決方案,幾乎沒有人能比他們更快地完成任務。
-
高產。他們是高產的程序員,代碼量極高,堪稱 “卷王”。
-
坑多。他們往往傾向于簡單地進行功能堆積,忽視抽象建模,將成本放到未來,由后來人買單。
從戰(zhàn)術龍卷風的特點可以看出,戰(zhàn)術編程(抽象)是缺乏或者說忽視抽象建模和系統設計的,聚焦于快速交付,系統能用就行,注重短期收益而非長期價值。當然,這并非完全是軟件工程師的問題,不合理的評價體系和行業(yè)特點亦難辭其咎。
?
3.2 方案二:深入分析,透過表象,探尋本質
方案一中 “草率” 地進行抽象建模是不可取的,于開發(fā)者自身而言,是一種茍且,無能力提升;于軟件項目而言,隨意堆積一次性代碼,將成本放到未來,是一種不負責任的行為。
如果我們深入分析業(yè)務,我們會發(fā)現,其實有更好的方案,而且并不復雜。如圖 5 所示:首先,忽略 PRD 描述中那些無關緊要的細節(jié),可以發(fā)現,PRD 涉及兩種場景;然后,針對兩種場景,進一步抽取共同特征——場景 S : N 次/周期 Q;最后,洞見共同特征背后的本質——周期維度記賬。
圖 5 基于業(yè)務抽象建立模型?
基于【周期維度記賬】這一需求本質,我們建立的模型不僅可以滿足當前業(yè)務的需要:
-
用戶點擊按鈕:DB 里面落一條記錄,其中 scene 可設為 “CLICK”。當用戶再次進入對應頁面時,先根據 userId 和 scene 查詢記錄,若存在,則說明用戶已經點擊過按鈕,告知前端無需展示“霸屏”動效。
-
用戶未點擊按鈕:DB 里面落一條記錄,其中 scene 可設為 “EXPOSE”。當用戶再次進入對應頁面時,先根據 userId 和 scene(CLICK)查詢、判斷用戶是否點擊過按鈕,如果沒有點擊,則根據 userId 和 scene(EXPOSE)查詢、判斷并更新曝光次數 count。
與此同時,基于【周期維度記賬】這一需求本質,我們建立的模型具有更好的可復用性、可擴展性。舉兩個例子:
-
多周期:基于字段 quantum 和 bizDt,可以支持終身、年、月、周、日等時間維度記賬。滿足不同業(yè)務場景的需要。
-
多場景:基于字段 scene,可以實現不同業(yè)務場景的數據隔離,同時支持多個場景,以及數據分析等附加需求。
4. 抽象并非一蹴而就!需要不斷假設、驗證、完善
如圖 6 所示,在人類文明早期,人們基于直觀地觀測,認為地球是宇宙的中心,因此抽象出了 “地心說” 模型。隨著時間的推移和觀測手段的進步,人們觀察到的天文現象越來越多,逐漸意識到 “地心說” 模型與觀測結果存在矛盾,于是,人們開始對 “地心說” 模型進行修正(像極了程序員重構模型),典型如 “本輪-均輪” 模型。
然而,隨著更多的天文現象被發(fā)現,在 “地心說” 模型的大框架下,無論如何修正都無法自圓其說。在 “地心說” 模型統治人類 “天文世界觀” 很長一段時間后,勇敢的先行者推翻了 “地心說” 模型,并提出了在當時看來離經叛道的 “日心說” 模型。
圖 6 “地心說”到“日心說”的發(fā)展史概略圖?
從 “地心說” 模型被提出,到 “日心說” 模型被廣泛接受,跨越了 1400 多年的時間。這一史實表明,人們對事物本質的探索是一個過程,而非一蹴而就?。?!對于服務端開發(fā)而言,我們對需求的認知也是如此,初見之下,我們往往很難直接洞見其本質,而需要不斷假設、反復推演,最終才能抽象出較好的模型。
你可能會問——抽象建模如此麻煩,開發(fā)時間往往又不充裕,何必苦苦探尋所謂的本質呢?能用不就行了么?
如果你確有上述疑問,不妨換個角度,想一下 “核心競爭力” 的內涵。很多時候,我們并不缺乏解決問題的辦法、能力和資源,而缺乏的是對問題的識別、理解、抽象。當一個問題被抽象為足以刻畫業(yè)務本質的模型,并拆解到軟件項目維度的時候,面對確定的任務、清晰的目標,可以解決問題的人就非常多了。
某種程度上,解決問題的能力是重要的基礎,但若僅僅是解決問題還遠遠不足以稱為核心競爭力。對于服務端開發(fā)工程師而言,抽象建模能力比編程落地能力更重要,因為編程解決問題只是一種普通技能而已,而對具象事物(如業(yè)務需求)的高度抽象,探索事物的本質,需要我們從新的角度審視舊的問題,需要有創(chuàng)造性的想象力,這才是真正的難點,當然也是核心競爭力所在。
最后,不要茍且,不要應付。我們每一次對事物的深入思考、對表象背后本質的探尋,都是一次自我提升。
?
5. 推薦一本書
PS:本文內容節(jié)選自業(yè)界首部體系化、全景式解讀服務端開發(fā)的著作——《服務端開發(fā):技術、方法與實用解決方案》。
《服務端開發(fā):技術、方法與實用解決方案》一書取材自阿里和螞蟻集團的精品內訓課程,由資深服務端技術專家、技術講師、阿里第二屆技術講師課程大賽年度冠軍得主、CSDN 博客專家撰寫。該書理論與實踐結合,全景式、體系化地闡述了服務端開發(fā),核心內容包括以下兩個部分。
-
第一部分:服務端開發(fā)的技術和方法
首先介紹服務端開發(fā)的職責、技術棧、核心流程和進階路徑;然后從需求分析、抽象建模、系統設計、數據設計和非功能性設計 5 個方面展開,結合案例深入講解了服務端開發(fā)的實操方法和重難點,為讀者呈現服務端開發(fā)的全景圖,幫助讀者快速、體系化地掌握服務端開發(fā)的知識和方法。
-
第二部分:服務端典型問題的解決方案
針對高并發(fā)、高性能、高可用、緩存、數據一致性、冪等、秒殺等服務端開發(fā)實踐中的典型問題,給出了對應的解決方案和開發(fā)規(guī)范,同時還結合案例深入分析了不同方案的優(yōu)缺點。此外,還總結了接口設計、日志打印、異常處理、代碼編寫、代碼注釋等落地層面的行業(yè)案例和規(guī)范。
讀者對象
-
IT 從業(yè)人員:服務端開發(fā)工程師、客戶端開發(fā)工程師、產品經理、測試開發(fā)工程師等。
-
高校學生:計算機、軟件、自動化、電氣、通信等專業(yè)有志于進入 IT 行業(yè)的在校學生。
文章來源:http://www.zghlxwxcb.cn/news/detail-705487.html
目前,本書已經在京東、淘寶、當當、拼多多等電商平臺發(fā)售。在電商 APP 搜索關鍵詞?“服務端開發(fā)”、“服務端開發(fā)技術”,即可搜索到該書。?文章來源地址http://www.zghlxwxcb.cn/news/detail-705487.html
到了這里,關于阿里后端開發(fā):抽象建模經典案例的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!