接下來這一篇文章開始,我們要進入所謂 3-Tier 的『 Domain 』的部份,這個層級基本上就是專門處理每一間公司的『 domain knowledge 』,某些方面來說這個層級應該是最重要的。
接下來我們將要談談,在 《 企業應用架構模式- Martin Fowler 》這本書中所提 domain 的三種 patterns 的第一種『 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 功能不一樣 :
備註: 資料庫事務與 ACID 不太熟的建議去過我的幾篇文章 :
書中是有提到 :
當 Transaction Script 越來越複雜時,會越來越難保持良好的設計,問題在於事務之間的冗余程式碼,因為裡面的程式碼都是專門用來處理該事務的
我這裡提出幾個我覺得問題點 :
但書中也提到個重點
有些事務的邏輯本來就簡單,硬要設計成 domain model 的寫法,反而不是好事。
這個模式簡單、快速,所以這種模式事實上非常非常的常見,我幾乎待過的公司都有看過,包含現在公司也是,我覺得也因為簡單、快速這個優點,所以大部份專案一開始的時後,除非有專職的軟體架構師在,不然大部份以 MVP ( minimum viable product ) 為導向的產品,大約 87% 都長這個樣子。
但這個最後苦的一定是後人。
就是我現在碰到的程式碼,就基本是前人遺留下來的 Transaction Script,然後我就是後人,我總於知道我接觸那麼久的東西就叫『 Transaction Script 』。
書中有提到一句話 :
早期選擇正確的策略,通常是最好的方法