互聯網公司的架構設計要怎么落地?


  你做架構設計了嗎?你認為要不要做架構設計?你的公司有沒有做架構設計?互聯網公司的架構設計又要怎么做?我不知道你是怎么想的,在我得到的答復中,大部分人認為要做架構設計,但自己卻很少做,自己經歷的公司也少有做架構設計。這里是矛盾的,難道大部分人和公司都犯錯了嗎?應該不是這樣。專職的架構師越來越少,架構部門也大都解散,為什么會是這樣,我們該怎么辦?

一、初識架構設計

軟件工程一般可分為需求、設計、編碼、測試、部署、維護。既然架構設計是一個過程,那么就有輸入和輸出。架構設計輸入的是PRD產品說明書,輸出的是架構設計文檔,中間是處理過程和工具,具體如下:

  • 輸入:功能需求和非功能需求,從PRD中提取;
  • 過程和工具:
  • 設計的目標和思路
  • 功能設計:用例視圖、用例活動圖
  • 應用:邊界、邏輯架構、接口、領域圖
  • 數據存儲
  • 物理架構、安裝部署
  • 非功能設計
  • 輸出:設計說明書,表述工具有Word、Visio、UML等

需求是我要什么即What,而架構設計是我要怎么做即How。架構設計為施工階段提供了指導,有利於接下來的編碼、測試、部署和維護,包括項目排期、人員分工、配合、單元測試、物理部署、系統修改和升級。設計是施工的計划,沒有計划就沒有管理,計划可節約施工的成本和時間。如果沒有架構設計就開始寫代碼,會導致很多的問題,干着干着就干不下去了,或干到一半必須得改等等現象。

二、應用架構設計案例

以下是一個真實的應用架構設計案例,《國內航班查詢引擎項目》的架構設計過程如下:

2.1 功能清單

產品經理提供的PRD文檔做得怎么樣,第一眼就看它有沒有功能清單。下圖的功能清單表格主要有兩個核心功能,一個是查詢航班數據模塊,另一個是清理緩存模塊。

2.2 用例圖與用例活動圖

上圖是用例圖和用例活動圖,用例圖有查詢航班數據和清理緩存,這與功能清單有對應關系。每一個用例都可以展開為用例活動圖,產品經理的活動圖關注的是業務的邏輯,我們的用例活動圖關注是程序的業務邏輯,有更多的技術視角。如圖所示,前台網站或Mobile發起查詢請求后,經過參數驗證,然后分別獲取政策、獲取貼點、獲取價格、獲取航班數據,再合並計算數據,最后構建返回數據。

2.3 領域圖

上圖是領域圖,它從用例活動圖演化而來,圖中的行為與活動圖有對應關系。如圖所示,平台或Mobile觸發查詢引擎后,然后多線程獲取政策數據、貼點數據、價格數據和航班數據,然后進行合並計算。領域圖是應用程序的業務邏輯模型,它的每一個框有可能是一個類,也可能是一個類庫,或是一個應用、一個子系統,它是可大可小、可伸縮、可擴展的。

2.4 接口設計

什么是接口?接口是契約、連接和交互,它是應用與外部世界的聯系者。有一位資深架構師說過,“我只需要設計好一套接口,讓整個業務流轉起來,我的工作就做完了,至於怎么實現我可以不知道”,這話有一定道理。以上契約遵循統一的Request/Response實現模式設計規范。

2.5 分層設計

2.6 代碼實現

左上圖是第一個版本的代碼實現,例如SearchVerify實現驗證查詢參數、CaculateBusiness實現合並計算、PolicyBusiness實現政策相關邏輯、PriceBusiness實現價格相關邏輯、DiscountBusiness實現貼點相關邏輯、CacheBusiness實現緩存邏輯、UserBusiness實現用戶邏輯。右上圖是第二個版本,相對第一個版本的實現要復雜些:ValidateBusiness對應驗證查詢參數、CaculateBusiness對應合並計算、PolicyBusiness對應政策、PriceBusiness對應價格、TiedianBusiness對應貼點、FilterPolicy對應政策過濾。可能你已經發現,不管代碼怎么升級改造,只要領域模型沒有發生變化,業務模塊也就不會發生大的變化。

架構設計會改變編碼方式,在架構設計階段如果做好了領域模型,你就可以在編碼施工階段,先寫業務邏輯層再寫數據訪問層。先定義好業務服務和數據接口定義,再根據數據定義來實現數據訪問。這與表驅動的傳統方式有所不同。先寫數據層再寫業務邏輯層,是先寫好數據表的增刪改查,然后業務邏輯層只是簡單地調用一下數據層,便提供給界面層使用。它只是一個簡單代理,完全沒有發揮業務邏輯層應有的價值。

2.7 其它設計項

除了以上設計項,還有數據庫設計、物理架構設計、非功能性設計。數據庫設計有E-R圖和表設計,物理架構設計有應用集群、應用部署圖、域名等,非功能性設計有性能、可用性、伸縮性、擴展性、安全性等。最后是總結和表述,輸出一份架構設計文檔,詳見下圖和附檔鏈接。

2.8 演化

以上是架構設計的關鍵過程,一環是功能需求,下一環是代碼實施,從功能需求到用例圖,到用例活動圖,到領域圖、架構分層和核心代碼,以領域模型為中心去構建業務邏輯代碼,然后再實現數據庫的訪問。它們之間環環相扣,做不好領域圖可能源自沒有做好用例活動圖,因為用例活動圖是領域圖的上一環。從功能到圖紙到代碼,從代碼到圖紙到功能,這是一個可演化可追溯的過程。架構設計如同施工圖紙,能直接指導工程代碼的實施,以及編碼施工次序的改變。

 

三、更多知識探討

什么是探討,什么是培訓?培訓是我有知識和經驗,然后教給大家,我是正確的,大家照着干就可以了。而探討是我有一個很好的問題,來問大家,來請教大家,以啟發你我的思維。接下來,與你一起探討以下架構知識:

3.1 設計表述探討
  1. 一定要有架構設計文檔嗎?按教科書是需要的,但真實的情況可能並不是這樣,沒有設計文檔的情況並不少見。
  1. 架構設計文檔要不要保存?項目做完后,它要保存多久呢?你待過的公司有保存嗎?我們要沉下心來問問自己,追求真實比書本更為重要。
  1. 設計文檔到底在為誰服務?為自己還是為別人?為半年后的自己,還是為公司或同事?
  1. 設計可以省掉嗎?在沒有設計文檔的前提下,是否可以編寫高質量的代碼?如果文檔可以省掉,那么架構設計過程呢?

架構設計文檔的編寫並不簡單,可能要花一周或一個月的時間,成本較高。設計表述方式有多種,具體如下:

  • 架構設計文檔:它相當於造房子用的施工圖紙,是相對比較正式的方式;
  • 需求分析設計或項目排期會議:PRD出來后,研發成員一起開需求分析設計會,分析討論的過程也是設計的過程。或者通過項目排期,在估算項目難易程度和排期時,也有設計分析的成分;
  • 設計郵件:一份簡單的設計郵件,內容大約有:問題描述、原因分析、技術方案、架構建議等;
  • 非正式討論:幾個人站在白板前,討論和畫畫,會議結束后再把它拍下發給參與人員。
3.2 關於UML

UML是Unified Modeling Language縮寫,又稱統一建模語言,是始於1997年一個OMG標准。它是一個支持模型化和軟件系統開發的圖形化語言,為軟件開發的所有階段提供模型化和可視化支持。它不僅統一了Booch、Rumbaugh和Jacobson的表示方法,而且對其作了進一步的發展,並最終統一為標准建模語言。UML圖型主要有用例圖、時序圖、活動圖、類圖、狀態圖、組件圖和部署圖。

UML是設計表述和建模工具,雖然它的願景是全生命周期,甚至用UML直接生成可執行軟件。實際上這是很難的,不到真正寫代碼,不可能明確所有細節。當然,UML在設計過程中還是有一定作用的,例如時序圖、類圖、狀態圖,這些如果不用UML圖來表示而用文字來描述的話,大家很難達成一致理解。

UML是理想建模工具嗎?那什么是理想的建模工具呢?船泊業3D建模,在未生產前就在電腦里把整個船構建起來。塑膠建模工具ProE、商品房售樓部的沙盤,在未見實物前就可通過模型知道很多信息。理想建模工具應該是3D的、動態的、簡單而形象的。UML只是一種表述你頭腦中思想的工具,相對而言你頭腦中的思想才重要,所選用的表述工具要根據雙方的實際情況,簡單清晰、利於溝通才是目的,並不一定就是UML。

3.3 關於設計模式

設計模式是一套被反復使用的、多數人知曉的、經過分類的、代碼設計經驗的總結。使用設計模式是為了重用代碼,讓代碼更容易被他人理解。 設計模式於己於他於系統都是多贏的,設計模式使代碼編制進一步工程化。每種模式都描述了一個不斷重復發生的問題,以及該問題的核心解決方案,項目中合理地運用設計模式可以很好地解決很多問題。GoF的設計模式共有23種,理解意圖是運用設計模式的關鍵,一圖勝萬言,下面是圖解23種設計模式。

設計模式是代碼的形狀,是代碼結構設計的招式,是練功的套路,如同書是人類進步的階梯。但練功是練功,打架是打架,真正的功夫要在大規模實戰中所得。從設計模式到代碼,再從代碼重構到設計模式。設計模式不僅是設計出來的,也是重構「長」出來的。雖然重構並非一定會得到與設計模式完全相同的抽象結果,但重構是設計模式的迭代補充。設計模式如果使用得過早過多或不恰當,會給代碼增加不必要的結構復雜度。重構和模式設計的良好結合,使代碼更趨於品質和實用。GoF設計模式是始於1995年的經典,主要解決當時軟件的重用性、擴展性和可維護性問題。而在20多年后互聯網時代的今天,版本迭代快、可隨時在線更新,使用環境、語言和框架都已發生變化,許多模式是否還合時宜?設計模式在面試的時候用得多,還是在實際開發中用得多?可能每個人答案都不一樣,但每個工具都有其適用場景、收益和成本,思考這些有利於我們更好地使用它。

3.4 關於設計原則SOLID

設計原則是設計模式的關鍵所在,原則和方法是決策的思想指南,設計原則SOLID具體如下:

  • 單一職責原則SRP:一個類只做一種類型的責任,一次只做一件事;
  • 開閉原則OCP:對擴展開放,對修改關閉。開閉原則具有理想主義的色彩,它是面向對象設計的終極目標;
  • 里氏代換原則LSP:任何基類可以出現的地方,子類一定可以出現,它是一個建議或約定;
  • 接口隔離原則ISP:不能強迫用戶去依賴那些他們不使用的接口;
  • 依賴倒置原則DIP:高層模塊不應該依賴低層模塊,但它們都應該依賴抽象,客戶第一。
3.5 關於DDD

DDD是Domain Driven Design的縮寫,翻譯為領域驅動設計,它的核心是領域模型。什么是模型?裝修人員從來沒看過你的房子,但看過以下模型后,就能知道你要裝修成什么樣。它的價值在於導航、精煉、統一表述。它能夠幫助施工方和客戶,全方面和多角度地去看待問題,而不是盲人摸象。它是利於溝通、實現、維護和擴展。

什么是領域?領是領地的意思,域是邊界的意思。領域是一個專業科目,是人為的划分,一個領域一個邊界一個框,領域會隨着規模、角度和時代的變更而發生變化。例如,公司規模很小的時候,沒有財務部,一個人既當會計又當出納。當公司規模變大一些時,可以一位做會計,一位做出納,可划分兩個領域。當公司規模變得更大的時候,領域又變了,成立財務部,財務部里有N位,每人干的事情都不一樣。業務在變,認知在變,領域的划分也要變。領域是主觀的,它是對客觀世界的階段性認知。

領域模型處於業務問題與技術解決之間,先將業務對象抽象成領域模型,然后根據領域模型來實現技術對象。從對象到類再到對象,從具體到抽象再到具體,我們對抽象和具體再做進一步引申。請問,是先有雞還是先有蛋?這個問題不好回答,給你一只具體的雞和一個具體的蛋,你便能知道它們是父子關系、子父關系或沒有關系,但是如果給你一只抽象的雞和一個抽象的蛋,你是不知道它們是什么關系的。再請問,是先有類還是先有對象?這個問題也不好回答。在設計階段,是先有對象再有類,在編碼階段,是先有類然后再有對象。整個過程是:架構師在設計階段根據業務對象抽象出類,然后程序員在編碼階段,先編寫類然后再New出一個對象。從對象到類再到對象,從業務問題到領域模型再到技術解決方案,從問題域到領域模型再到代碼實施,這是領域驅動的核心所在。領域驅動設計=從問題域驅動領域模型構建+從領域模型驅動代碼實施。

 

以上是DDD的分層架構,包括倉儲層Repository Layer、領域層Domain Layer、應用層Application Layer、表現層Presentation Layer、基礎設施層Infrastructure Layer。從倉庫中取出原材料,然后流水線將人、材料、工具組織起來,最后輸出給表現層。上圖中,領域層不依賴於倉儲層,而是倉儲層依賴於領域層。這相當於傳統三層中業務邏輯層不依賴於數據層,而是數據層依賴於業務邏輯層。為什么要這樣呢?這是因為上層需要什么下層就提供什么,而不是下層有什么就提供什么,客戶第一、按需生產都是這個道理。在技術的具體實現上即依賴倒置DIP,把接口放在上層,然后下層實現,最后使用IoC工具綁定即可。

3.6 設計不足與過度設計

什么是設計不足,什么是過度設計?不能解決當前問題的就是設計不足;只能解決當前問題的是恰當設計;能解決當前問題,且又能解決未來一段時間問題的是良好設計;能解決當前問題,但面向未來設計過多,且成本較大,預測錯誤又不能解決未來問題的是過度設計。我們要追求恰當設計或良好設計,特別是互聯網項目,變化大、迭代快,很難預測未來發生的事項。

那什么是好的設計呢?好的設計是實用的、易於理解的,是謹慎克制的、簡單的,是能夠落地的、考慮施工成本的。好的設計要解決業務的問題,你的設計再牛逼,但不能解決業務的問題,那么這個設計就是不好的設計。好的設計是謹慎克制的,不能為Show技術或個人意願而過多使用復雜的技術。好的設計是能夠落地的,如果你的設計在落地上出現很多問題,那么就是有問題的設計。沒有人在設計時失敗,只有實施時失敗。

3.7 架構設計是藝術

以上架構知識非常重要,但並不是知道了這些,就能做好架構設計了。這如同很多人都會畫圓和直線,但並不會畫畫;很多人會使用釘板和菜刀,但並不能做一桌美味的佳餚。

我們探討一個具體的問題,“能異步的盡量異步”,互聯網公司程序員經常說的這句話,是否正確?首先,程序員喜歡同步還是異步?用戶喜歡同步還是異步?程序員為了並發量,會選擇異步。用戶不要等待,要求系統立即返回,會選擇同步。那么在什么情況下使用同步,什么情況下使用異步呢?有幾個考慮因子,第一個是復雜度,同步=異步+輪詢/通知,同步相對簡單,異步則相對復雜。第二個是可靠度,如果是2/5/8秒概率較大,那么最好選用同步。第三個是用戶體驗,當使用異步后,用戶體驗也需要改進,可立即返回給用戶一個單號和進度條。第四個是業務成熟度,業務成熟度分萌芽期、發展期、成熟期、衰退期這四個階段。對於新業務,能同步就同步,當業務變得越來越成熟,訪問量越來越大的時候,容易出現高並發量導致用戶排隊,這時異步是挺好的選擇。

在實際問題面前,選擇同步還是異步?要看情況,需經過分析、思考,你需要知道每一種選擇的利弊。分析的過程往往比決策更為重要,當你知道了每一種選擇的利弊,這時你喜歡就好,因為你只有喜歡了才能把事情辦得更好。你的架構設計=你+架構設計,架構設計是科學,你是主觀意識,最后的決策一定包含了你的個性和情感。科學到最后是藝術,架構設計是藝術。

 

四、互聯網公司的架構設計要怎么落地

互聯網公司的架構設計是怎么做的呢?專職的架構師越來越少,架構部門也大都解散,為什么會是這樣,我們該怎么辦?

4.1 要不要做架構設計

哪些項目需要做架構設計呢?越大的項目越需要做架構設計,開發時間越長的項目越需要做架構設計,參與人員越多、內部越復雜、外部依賴越多、影響面越大、維護成本越高的項目越需要做架構設計。那互聯網的項目呢?它有以下特征:

  • 時間:開發的周期整體很長,可能維護10年、20年,但單個應用的開發周期短,多半以天和周為單位;
  • 規模:互聯網項目整體很大,但單個應用規模小,會被拆分為多個小應用;
  • 業務知識:為自己做系統,行業知識不缺,長期為一個系統服務,有些自己也是客戶;
  • 復雜度:研發人員多,內部關系復雜,外部依賴多,變化大迭代快,在不斷地演化,24小時不間斷運行。
4.2 MVP與架構設計

MVP的英文全稱是Minimum Viable Product,是最小可行性產品的意思。如上圖所示,用戶需要一個交通工具,有兩種實現方式,第一種做法是分多個階段設計與制造,第一步是造一個輪子,第二步是造兩個輪子,第三步是造一個蓋子,第四步是一輛可用的轎車。第二種做法是每一階段都要滿足用戶從A地到B地的需求,第一步先造個滑板,第二步是造個自行車,第三步是造輛摩托車,第四步是造輛轎車。第一個版本到第三個版本輸出的產品都可以滿足用戶的基本需求,雖不完善但可以解決用戶的問題,並且越來越好,到了第四個版本的產品才是客戶預期。

MVP對架構設計提出更高的要求。如果單純從研發內部的角度,第一種是施工成本較低的方案,但我們需要以客戶為中心,需要不斷地滿足客戶的需求,所以在做設計時,不僅要考慮施工的成本,還有客戶需求、擴展性、繼承性等,如上圖第三種設計方案。

4.3 互聯網公司是怎么做的

互聯網公司的架構設計是怎么做的,當前主流做法有:

  • 分工:將技術研發和業務研發相分離,下層是雲平台部或基礎架構部,提供IaaS、PaaS中間件等雲服務,上層是各業務線的產品研發部,專注於業務場景的應用研發;
  • 敏捷:業務研發敏捷化,產品與研發、測試實時溝通,以減少行業知識的缺乏;
  • 整體:技術委員會,負責技術總體規划和技術成長;
  • 未來:研究院,解決未來的技術問題,如阿里達摩院、百度研究院;
  • 應用架構:主要負責技術與業務的結合,由應用架構師、技術經理或高級程序員擔當。
4.4 應用架構要怎么落地

應用的架構設計要怎么落地,常見如下:

  1. 總體架構規划:手握地圖,才能明確自己所處的位置,以便於配合。總體架構規划可以讓每個研發人員了解整體,它如同房子的地基框架圖紙,可長期保存和更新維護。具體參考TOGAF開放組體系結構。
  1. 單個項目架構設計:重點項目一定要做架構設計,參與架構評審,非重點項目可簡化設計表述。
  1. 應用架構評審:以流程的方式來保證應用架構設計的質量,例如重構項目、跨部門項目、業務核心項目需要經過應用架構評審之后,才能申請服務器、數據庫、域名等。
  1. 其它工作:如果有應用架構師專職人員,除以上工作外,還包括統一公司應用分層、制定代碼規范、組織技術培訓、中間件推廣、應用性能調優等。
五、你給技術打個分

以上,首先是一個啟發性的問題,然后是初識架構設計,接着是一個真實的應用架構設計案例,並探討了更多架構設計知識,包括設計表述、UML、設計模式、設計原則SOLID以及DDD,最后是互聯網公司要怎么落地。這些知識點都是工具,這些工具到底怎么樣呢?如果它是一個新知識,我們不好妄加評價,但這些工具已經出來很多年了,我們也工作了這么多年。它好不好用,實不實用,我們都應該知道些。現在,大家也當回老板,請你給技術打個分,以下二維碼是鏈接,歡迎績效考評 :-)

六、案例參考

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM