企業及應用架構V

發現領域架構

Posted by BY Skyleaf on February 7, 2019

前言

這篇稍微紀錄一下這次讀本書第五篇的感想,這篇前面再講很重要的 ubiquitous Language (統一語言)Bounded Contexts (綁定上下文)。但我想記錄其中的 Context Mapping(上下文映射)The Layered Architecture (分層架構篇)

图

Agenda

  • Context Mapping(上下文映射)
  • The Layered Architecture (分層架構篇)

前提

  • 這篇算是進入領域模式的開章,綁定上下文沒有一套完美的走法來告訴你如何實現,界定上下文的邊界取決於你的商業模型,時間,人力甚至技能。但這裡有兩個我一直搞混的東西,那就是在架構上,常常把硬體的架構跟軟體的架構混在一起,其實也是因為我們對整體 ubiquitous Language 沒有定義好才導致的,因為在公司內部要有人懂這塊基本上太難,有幸遇到說不定當時我也聽不懂,直到慢慢的累積學習到的經驗,開始發現本書內的某些解釋都可以呼應到以前遇到的種種問題,這時候才真的覺得原來如此,有時候太早看到此書也沒用,因為本身的能力的體驗還不到那階段。回到本篇文章,不管是在做專案還是討論任何的議題,統一語言是非常重要的,這可以大大節省成本。很多搞混也是語言上的模糊不清才導致後續的不明白。回到我剛剛說的問題,在硬體架構我們要說Tier。在軟體架構我們要說Layer,而常常我們把這兩個混在一起了。DDD裡的 Strategic Model Design 策略模型設計 階段就是來評估架構方案的,還有就是每個綁定上下文所適合的架構,聽到這裡大家應該是點點頭。看看下面Bounded Contexts範例如何。

Bounded Contexts

具體一點,一個購物網站,他會有的專案不會只有B2C,他還會有B2B,B2E,Job等等專案,甚至一些內部專案。這些整體來看都屬於DDD的規範(硬軟體)。當你劃分好上下文跟上下文邊界後,你就可以設計每個上下文的合適架構。每個喔,可以是不一樣的。B2C以現在流行的方式可以是SPA + WebAPI。B2B可以是ASP.NET MVC,以此類推。如果遇到需要共用的上下文,例如會員,剛好有兩個前台B2C網站或是手機網站或是APP程式,會員在這裡就可以有不同的劃分。我的作法會建立一組可共用的會員驗證Server,也就是一個專門發放Token的服務,使用JWT機制架上Refresh Token方式。有點像是Google或是Facebook的OWIN。在重疊的上下文方面,本文有其介紹:

  1. 在重疊的會員可以劃分成一整個上下文,B2C的兩個網站全部包再一起整個上下文,整個包含在內。
  2. 如果會員就希望是可以共用的也可以劃分B2C-1,B2C-2,共享內核(會員)。(我使用這個方式)
  3. 最後的方式還可以劃分每個前台網站有自己的會員,上下文都有自己的會員。

最終取決在於你當下的環境,沒有對錯。

附上一張本文的重疊 Resolving the conceptual overlapping of contexts.

重疊

  • 以上是本文三種方式介紹,你說還會不會有其他的方式,我相信是有的。

Context Mapping(上下文映射)

這裡要講一個整體的大圖,做任何事情前,第一件事就是有明確目標,然後有一個大圖願景,讓你可以清楚知道整體範圍。在DDD裡面定義了一些 Relational Pattern 關係模式 ,這個模式定義了上下文之間的關係,使用 Upstream Context 跟 Downstream Context來標示上下文關係。以下是關係模式:

  1. Anti Corruption Layer 防腐層 : 通常使用在對接外部單位,由於不讓upstram Contexts異動而影響到downstream Contexts,防堵方式就是ACL,透過這層我們可以盡可能讓上文的異動不引響了下文的Contexts
  2. Conformist 從屬 : 屬於ACL的輕量級模式,下游的context會被動地接受上游的context模式,下游會接受包含他用不到的數據。
  3. Client/Server 客戶跟供應商 : 這在以前做物流範例很常用到,供應商只會給客戶他需要的數據資料,這是跟Conformist模式的最大差異。
  4. Partnership 搭擋 : 兩個上下文是分開的,不共享程式碼,但兩個上下文同時是對方的上下游,互相依賴。
  5. Shared kernel 共享內核 : 就是兩個上下文會去共享使用這個子model。耦合相對高。

附上一張本書內的上下文映射 A sample context map showing some of the DDD relational patterns.

DDDMapping

The Layered Architecture (分層架構篇)

我以前一直搞混DDD的架構跟分層架構,感覺可以混在一起,但又有些不同,其實他是不一樣的,如果沒釐清界線很容易就搞混,討論起來就很模糊,DDD是一種架構設計,他的範圍比較大,還可以細分到使用其他的架構模式。記得每個上下文都可以有自己的架構。B2C專案不一定使用ASP.NET MVC。可以是.NET Core。這裡介紹支持的架構,但我先列出他們,因為有些內容尚未搞清楚,寫出來怕誤人子弟,而且每個架構都可以大篇幅的在探討,在這裡就不細講了。

  1. Multilayer architecture
  2. Multitier architecture
  3. Client/server architecture
  4. Domain Model
  5. Command-Query Responsibility Segregation (CQRS)
  6. Event sourcing
  7. Monolithic architecture
  8. Micro-Service

這裡我想記錄的是一個我以前搞混的狀況,需要說到以前我們使用的三層式架構,我們會把class區分成Presentation Layer,Business Logic Layer,Data Access Layerc。這也就是架構,不然你都寫一起就產了。但這是軟體的方式,硬體呢? 你會開一台IIS跟一台DB Server,還有AP。靠就是這AP搞死我的。以前我剛聽到的時候我就覺得怪怪,我不明白這是軟體架構還是硬體架構,還是整體架構。直到現在還是有人這樣搞混。其實AP server是指應用程式伺服器,阿裡面是啥,阿不就是IIS。所以就是再說Tier阿,那不就是硬體架構。你Google看看還可以看到很多網站介紹這是軟體架構。當然如果你什麼東西都只放在一台機器那就比較難區分了。Infra會說AP Server,DB Server,File Server,Log Server。多半都是再說硬體位置。而已前寫軟體的MIS都比較資深,所以RD常常會被拉著鼻子走,因為根本沒有架構師這號人物。如果你把邏輯層的架構部屬到物理層的架構上,你的服務就會有延遲,因為網路是有頻寬的,以前聽到作專案,在討論架構期間,常常會有這種哪裡怪怪的,就是因為物理架構(Tier)跟邏輯架構(Layer)搞混了。那現在呢? 看本文推薦:

那本文推薦的現代版架構是:

  • Presentation Layer:
    • Vue,Razor Page,React,Angular
  • Application Layer:
    • Controller
  • Domain Layer:
    • Model,Service 邏輯部分
  • Infrastructure Layer
    • Ioc,Cache,Repository

附上一張本文的架構圖 A more modern version of a layered architecture.

Imgur

順道奉上我目前擅長的架構方式:

Layer:

  • Presentation Layer:
    • Vue
  • Application Layer:
    • Web API Controller,IoC
  • Domain Layer:
    • Model,Service 邏輯部分
  • Utility (Cross Cutting) 這層跟Infra有類似
    • Cache,Dapper,ADO.Net,Logger,
  • DAL Layer 這邊一直是我沒符合DDD的原因
    • Repository

Tier:

  • AP Server (Member)
  • AP Server (B2C主要的邏輯網站)
  • AP Server (B2B)
  • AP Server (內部維運網站)
  • Log Server (統整ELK)
  • Cache Server (Redis)
  • AP Server (Schedule Job 排成)
  • Queue Server (RabbitMQ)
  • DB Server

來源

  1. Microsoft.NET企業級應用架構設計
  2. 圖片來源Microsoft .NET: Architecting Applications for the Enterprise