公司新來的阿里P7大牛,只用十分鐘就教會了我實現高層次的複用

最新互聯網大廠面試真題、Java程序員面試策略(面試前的準備、面試中的技巧)請移步GitHubgit


做爲開發人員,你對複用這個概念必定不陌生。在開發過程當中,咱們把系統中通用的代碼邏輯抽取出來,變成公共方法或公共類,而後在多個地方調用,這就是最簡單的技術上的複用。程序員

但一開始,咱們不會過多地考慮複用,當一個新項目過來,咱們會選擇最直接的方式來實現,結果每每是欲速而不達,好比說:github

好不容易搞定了一個項目,接着又有新的相似項目過來,咱們又要從頭再來;項目的代碼是定製的,項目結束後,系統維護的噩夢剛剛開始。面試

若是項目缺少沉澱,每一個項目都是全新的開始,出現這些狀況,一點都不意外。而要想解決這個問題,咱們一開始就要考慮系統的複用性。算法

複用,它可讓咱們站在巨人的肩膀上,基於現有的成果,快速落地一個新系統編程

那麼,咱們在作架構設計時,如何實現系統的高可複用呢?架構

今天,我就針對複用這個話題,首先和你介紹一下,複用具體都有哪些形式;而後,我會針對最有價值的業務複用,帶你瞭解如何劃分服務的邊界,讓你可以在工做中,設計一個能夠高度複用的系統。框架

複用的分類

複用有多種形式,它能夠分爲技術複用和業務複用兩大類。技術複用包括代碼複用和技術組件複用;業務複用包括業務實體複用、業務流程複用和產品複用。ide

從複用的程度來看,從高到低,咱們能夠依次劃分爲產品複用 > 業務流程複用 > 業務實體複用 > 組件複用 > 代碼複用。微服務

公司新來的阿里P7大牛,只用十分鐘就教會了我實現高層次的複用

接下來,我就按照複用度從低到高,對這些複用方式進行一一分析,幫助你更好地理解架構的可複用性。

技術複用

首先是代碼級複用,這部分應該是你最熟悉的了。這裏包括你本身打包的類庫,第三方提供的 SDK,還有各類算法封裝等。咱們的代碼能夠直接調用它們,物理上也和咱們的應用打包在一塊兒,運行在同一個進程裏。代碼級複用是最低層次的複用,你能夠把它看成你本身源代碼的一部分。

再往上,是技術組件複用。這些組件有咱們本身封裝的,更多的是大量開源的中間件,好比Redis、MQ、Dubbo 等;組件也包括各類開發框架,好比 Spring Cloud。這些基礎組件技術複雜度很高,它們的存在,極大地簡化了咱們的開發工做。

值得注意的是,代碼級複用和技術組件複用都屬於工具層面,它們的好處是在不少地方均可以用,但和業務場景隔得有點遠,不直接對應業務功能,所以複用的價值相對比較低。

業務複用

咱們知道,系統最終是爲業務而服務的,若是可以實現直接的業務複用,那系統開發的效率就更高。在前面的課程中,咱們討論架構的演進過程時,不少地方談到了業務能力的複用,好比說,微服務強調單個業務實體的封裝和複用,而中臺進一步實現了企業級業務能力的複用。

因此接下來,咱們就從比較簡單的業務實體複用開始提及。

業務實體複用針對細分的業務領域,好比訂單、商品、用戶等領域。它對各個業務領域的數據和業務規則進行封裝,將它變成上層應用系統能夠直接使用的業務組件。

業務流程的複用針對的是業務場景,它能夠把多個業務實體串起來,完成一個端到端的任務。好比說,下單流程須要訪問會員、商品、訂單、庫存等多個業務,若是咱們把這些調用邏輯封裝爲一個下單流程服務,那下單頁面就能夠調用這個流程服務來完成下單,而不須要去深刻了解下單的具體過程。相比單個的業務實體複用,業務流程的複用程度更高,業務價值也更大。

最高層次的複用是對整個系統的複用,好比說一個 SaaS 系統(Software-as-a-Service),它在內部作了各類通用化設計,容許咱們經過各類參數配置,獲得咱們想要的功能;或者說一個 PaaS(Platform-as-a-Service)平臺,它會提供可編程的插件化支持,容許咱們「嵌入」外部代碼,實現想要的功能。

這種產品級的複用,它的複用程度無疑是最高的。這樣的系統,在落地的時候,它無需核心的開發團隊進行開發,只由外圍的實施團隊負責就能夠了,這樣,一個項目的上線就能簡化爲一次快速的實施,不但上線週期短,系統也更穩定。

固然,實現這樣的複用,難度也是很大的,你既要對所在行業的業務有很全面的理解,又要有很強的抽象設計能力。這類系統中,比較典型的有 Salesforce 的 CRM 系統和 SAP 的ERP 系統。

如今,咱們先對複用作個總結。從技術複用到業務複用,越往上,複用程度越高,複用產生的價值也越大,但實現起來也越複雜,它能複用的場景就越有限。在實際工做中,技術層面上的複用相對比較簡單,咱們對這部分的認知也最多,並且因爲開源的普及,如今有豐富的中間件讓咱們選擇,咱們能夠基於它們,逐步構建適合本身的技術體系。

但若是咱們能進一步打造業務中間件,並在這個基礎上,造成業務平臺,這樣,咱們就能實現更高的業務級複用,能夠更高效地支持系統的快速落地

而在實現業務組件化和平臺化的過程當中,首要的問題就是基礎服務邊界的劃分。邊界劃分決定了服務的粒度和職責,在實際工做中,也是很是困擾咱們和有爭議的地方。

接下來,我就針對基礎服務邊界的劃分,和你分享我本身在項目開發的過程當中,總結的一些實用的原則和作法。

基礎服務邊界劃分

服務邊界劃分要解決「我是誰」的問題,它實現了服務和周邊環境的清晰切割。

咱們都知道,服務包含了業務數據和業務規則,並提供接口給外部訪問,其中,接口是服務的對外視圖,它封裝了服務的業務數據和規則。

因此從邊界劃分的角度來看,咱們就是要肯定哪些數據屬於這個服務,哪些接口功能由這個服務提供。這裏,我總結了 3 個基礎服務邊界劃分的原則,供你設計時作參考。

首先,是服務的完整性原則

你在劃分服務的邊界時,須要確保服務內部數據的完整性。

舉個例子,一個商品服務的數據模型,不只要有商品基本信息,好比商品名稱、價格、分類、圖片、描述等;還須要包含商品的擴展信息,如商品的各類屬性、商品標籤等;最後還要包含各類複雜商品類型的定義,好比組合商品、套餐商品、多規格商品等。

另外,你還要保證服務功能的完整性。對於服務使用者來講,他們是以業務的角度看服務,而不是純粹的數據角度。好比一個套餐商品,在服務內部,它是多個單品的複雜組合,但從服務調用者的角度來看,它就是一個商品。

那如今問題來了,對於套餐的價格,商品服務是給出一個最終價格呢?仍是給出各個單品的價格,而後讓調用方本身算最終價格呢?咱們知道,套餐的價格不是各個單品價格累加的結果,它包含了必定的優惠,若是它的價格由服務調用方來算,這會致使商品的部分業務規則遊離於服務外面,破壞了商品服務的功能完整性。

在實踐中,有些服務只是存儲基礎數據,而後提供簡單的增刪改查功能,這樣一來,服務只是一個簡單的 DAO,變成了數據訪問通道。這樣的服務,它的價值就頗有限,也容易被服務調用方質疑。所以,咱們要儘量在服務內部封裝完整的業務規則,對外提供完整的業務語義,最大程度地簡化服務的使用。

因此,當你在劃分服務邊界時,要保證服務數據完整、功能全面,這樣才能支撐一個完整的業務領域

其次,是服務的一致性原則

也就是說,服務的數據和職責要一致,誰擁有信息,誰就負責提供相應的功能。

服務內部的業務邏輯要儘可能依賴內部數據,而不是接口輸入的數據,不然會形成數據和業務規則的脫節(一個在外面,一個在裏面),若是服務對外部的依賴性很強,就沒法提供穩定的能力了。

不少時候,咱們對一個功能到底劃分到哪一個服務,有很大的爭議。這時,咱們能夠結合這個功能所依賴的數據來判斷,若是功能所須要的大部分數據都存儲在 A 服務裏,那固然由 A服務來提供接口比較合適,這樣接口輸入的數據比較少,不但簡化了服務對外部的依賴,同時也下降了接口調用的成本。

給你舉個例子,在訂單小票上,咱們常常能看到一些優惠信息,好比說商品原價是多少,其中由於滿減優惠了多少,由於商品特價減免了多少。這個優惠計算的結果是訂單的一部分,毫無疑問,它須要保存在訂單服務裏。

但這個訂單的優惠計算過程,卻不是由訂單服務來負責,而是由獨立的促銷服務負責的。由於優惠計算所須要的優惠規則是在促銷服務裏定義的,促銷服務能夠在內部拿到全部的優惠規則,而後完成整個優惠計算。

不然,若是是由訂單服務負責優惠計算,訂單服務的調用者就須要在接口中提供完整的促銷規則,不但調用成本高,並且外部促銷規則的改變會影響訂單服務的內部實現。

因此在這裏,促銷服務負責促銷規則的維護,以及對應的優惠計算功能;訂單服務負責優惠結果數據落地,以及後續的查詢功能。這樣,每一個服務存儲的數據和對外提供的功能是一致的。

最後一個,是正交原則

既然是基礎服務,它們就處於調用鏈的底層,服務之間不會有任何的調用關係,也就是說基礎服務相互之間是正交的。好比說會員服務和商品服務,它們表明不一樣維度的基礎業務域,彼此之間不會有調用關係。

正交還有另一種狀況:服務之間有數據的依賴關係,但沒有接口的調用關係。

好比說,訂單明細裏包含商品 ID 信息,但訂單服務內部不會調用商品服務來獲取商品詳情。若是頁面須要展現訂單的商品詳情,針對這個具體的業務場景,咱們能夠在上層的聚合服務裏,經過聚合訂單服務和商品服務來實現。

總結

可複用是架構設計的一個重要目標,今天咱們對複用進行了梳理,包括複用有哪些形式,以及它們有哪些價值,相信你如今對複用已經有了一個總體的認識。業務上的複用比純粹的技術複用有更高的價值,咱們要儘可能往這個方向上靠。

在實踐中,落地基礎服務是實現業務複用的有效方式,而基礎服務邊界的劃分,它有科學的成分,但更多的是一種藝術,這裏我提供了幾個實用的劃分原則,你能夠在工做中結合實際狀況,靈活地運用它們。

相關文章
相關標籤/搜索