iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
自我挑戰組

馬克的軟體架構小筆記系列 第 11

30-11 之Domain Layer - Transaction Script

  • 分享至 

  • twitterImage
  •  

接下來這一篇文章開始,我們要進入所謂 3-Tier 的『 Domain 』的部份,這個層級基本上就是專門處理每一間公司的『 domain knowledge 』,某些方面來說這個層級應該是最重要的。

接下來我們將要談談,在 《 企業應用架構模式- Martin Fowler 》這本書中所提 domain 的三種 patterns 的第一種『 Transaction Script 』。

Transaction Script 是什麼呢 ?

Transaction Script organizes business logic by procedures where each procedure handles a single request from the presentation.

假設我們要實作一個『 購物車結帳 』的功能,我們有 87 % 的情況下,程式碼應該會寫成如下,就是一個購物車用的 service,然後裡面有結帳 ( checkout ),然後將結帳要做的每個 task 都寫在裡面。

備註 1 : 書中範例也是用 service 來做這個類別的分類。

備註 2 : dao 的概念你現在只要記它是去操作 db 就好,詳細的定義會在後面 Data Source 層級拿出來說。

class CartService{

	async checkout(){
     // 取出購物車要結帳的商品
		 const products = this.cart.items
     
     // 建立訂單
		 const order = await orderDao.create(orderBody)
     // 建立付款記錄
     const payment = await paymentDao.create(paymentBody)
     // 建立發票 
		 const invoice = await invoiceDao.create(invoiceBody)
	}
}

『 購物車( Cart )結帳 ( checkout ) 』這就代表一個事務,然後它裡面所要完成的事情為 :

  • 建立訂單
  • 建立付款記錄
  • 建立發票

這種最常見的寫法,就是所謂的『 Transaction Script 』。

這裡和資料庫的 transaction 功能不一樣 :

  • Domain - Transaction Script : 將要完成某個事務的任務都寫在一起
  • DB - Transaction : 確保事務有要就全部完成,不會有事務中某個任務執行失敗,導致資料不一致的事情。

備註: 資料庫事務與 ACID 不太熟的建議去過我的幾篇文章 :

那 Transaction Script 這種寫法有什麼缺點呢 ?

書中是有提到 :

當 Transaction Script 越來越複雜時,會越來越難保持良好的設計,問題在於事務之間的冗余程式碼,因為裡面的程式碼都是專門用來處理該事務的

我這裡提出幾個我覺得問題點 :

  • service 與 service 最後會變成有可能共用,而這樣就機率發生 cycle dependency。
  • 每個事務可共用的程式碼可抽出來,但要放那 ? 且它是給 service 用,但有沒有可能它需要某個 service 用的東西。
  • 每個 service 要處理範圍在那 ? 假設有兩個 service 分別為 Cart 與 Purchase,那結帳流程是要寫那 ? Cart.checkout 還是 Purchase.execute(products) 呢 ?

但書中也提到個重點

有些事務的邏輯本來就簡單,硬要設計成 domain model 的寫法,反而不是好事。

小總結

這個知識點可以用來解釋什麼現象

這個模式簡單、快速,所以這種模式事實上非常非常的常見,我幾乎待過的公司都有看過,包含現在公司也是,我覺得也因為簡單、快速這個優點,所以大部份專案一開始的時後,除非有專職的軟體架構師在,不然大部份以 MVP ( minimum viable product ) 為導向的產品,大約 87% 都長這個樣子。

但這個最後苦的一定是後人。

這個知識點可以和以前的什麼知識連結呢 ?

就是我現在碰到的程式碼,就基本是前人遺留下來的 Transaction Script,然後我就是後人,我總於知道我接觸那麼久的東西就叫『 Transaction Script 』。

我要如何運用這個知識點 ?

  • 在開發產品型的東西,不要為了快速與方便選擇 Transaction Script,後人維護與改寫成本非常的恐佈。
  • 專案型的我覺得可以。
  • 小工具型的我也覺得可以。

書中有提到一句話 :

早期選擇正確的策略,通常是最好的方法

參考資料


上一篇
30-10 之Presentation Layer - MVVM ( Model-View-ViewModel )
下一篇
30-12 之 Domain Layer - Domain Model ( 未完成版 )
系列文
馬克的軟體架構小筆記29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言