关于上下文映射看这篇就够了
本文摘自《程序員必備的思維能力》
限界上下文
任何問題都是有邊界的,這個問題的邊界也叫這領域邊界。也就是說,我們要對一個問題進行分析或者建模,一定是在一個特定的上下文(Bounded Context:限界上下文)下,而不可能是漫無邊際的亂討論。
因為語言的多意性和靈活性,會導致同一個概念,在不同的上下文呈現出不同的語義,包含不同的屬性。就像Apple,在水果賣場這個上下文下,它代表的是水果;而在手機賣場,它代表的是iPhone。同一個詞語因為上下文不一樣,其含義完全不一樣。
限界上下文告訴我們,同一個概念,不必總是對應于一個單一模型,也可以對應于多個模型。用限界上下文明確模型要解決的問題,可以保持每個模型的清晰。限界上下文是領域模型的邊界,也就是領域知識的邊界。和上下文主題緊密相關的模型內聚在上下文內,而其他模型被會分到其他限界上下文中。限界上下文內的領域知識是高內聚低耦合的。
比如商品作為電商業務最核心的要素,貫徹整個商業活動始終。在龐大的電商系統做領域化拆分之后,商品的概念也是滲透到各個子域當中,售賣的是“商品”,營銷的主體是“商品”,下單是針對“商品”的訂單,倉庫中存的是“商品”,履約是“商品”的送達等等。然而這些“商品”在不同的上下文下,表達的語義和內涵是不一樣的。
上下文映射
每一個上下文都有一套自己的“語言”,如果在該領域要使用其它領域的概念,我們就需要一個“翻譯器”,這個在不同領域之間進行概念轉化、信息傳遞的動作就叫上下文映射(Context Mapping)。上下文映射主要有兩種解決方案:共享內核和防腐層。
共享內核
所謂的共享內核(Shared Kernel),是指把兩個子域中共同的實體概念抽取出來,形成一個組件(java中的jar包),然后通過內聯(inline)的方式,分別被不同的子域使用。
還是以電商系統為例,商品域中的“商品”和售賣域中的“商品”雖然都叫商品,但是兩者的屬性是不一樣的,比如在商品管理中,主要關注的是商品的產品屬性和產品分類,主要是用來做商品管理,因為還沒有上架銷售,所以也就沒有商家屬性(sellerId)。而在售賣域,商品是用來面向消費者銷售的,相比較商品域中的商品或者產品,它多了商家屬性、售賣價格、營銷屬性、買點等更多的屬性。
鑒于商品域和售賣域中的“商品”大部分屬性都是相同的,我們可以考慮使用共享內核的方式。如下圖所示,將共同部分抽取成一個組件,由商品域和售賣域共享,這種方式的好處是最大程度的代碼復用和能力共享,然而壞處也很明顯,即高耦合:任何對于“共享內核”的改動都要小心翼翼的協調兩個領域的技術團隊,且會影響兩個領域。說實話,這個副作用有點傷不起,所以在實踐中,更推薦的上下文映射方法是防腐層。
防腐層
所謂的AC(Anti-Corruption:防腐層),在一個領域中,如果需要使用其它領域的信息,可以通過AC進行防腐和轉義。實際上,在微服務的環境下,服務調用是一個普遍的訴求,因為沒有一個服務是孤立的,都需要借助其它服務提供的數據,共同完成業務活動。
同樣是上面的電商場景,如果采用AC的方式進行上下文映射的話,我們需要在售賣域中建一個AC模塊。因為售賣域在商品上架銷售的時候,需要從商品域獲取商品的信息,在分布式環境下,這種信息獲取可能是RPC調用,也可能是REST,通訊協議可能不一樣,但并妨礙信息的載體都是商品DTO(Data Transfer Object)。AC的作用就是要把外域的DTO轉義成自己領域內的概念。
這樣做雖然有一定的代碼重復,商品信息在商品域和售賣域都有一定的重復。但是解耦非常徹底,售賣域的AC起到了“防腐”的作用,商品域的任何變化并不會直接影響到售賣域,雙方都擁有了更大的自主權和靈活度。系統架構就是這樣,我們永遠要在重復(Duplication)和復用(Reuse)之間去一個折中,進行權衡。關于更多AC的設計細節,我會在COLA一章中進行更加詳細的介紹,這里就不多說了。
總結
以上是生活随笔為你收集整理的关于上下文映射看这篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 小米手机播放短小音频无声
- 下一篇: vue在图片标注矩形框