企業軟體架構模式 - ch9.1 Transaction Script (交易指令碼)

按照「程序」來組織商業邏輯,
其中每一個程序負責處理來自展示層的單一請求

大多數的商業邏輯都可以被視為一系列的交易(transaction),每一個交易都有自己的 Transactin ScriptTransactin Script 主要是將這些邏輯組織封裝成為單一程序。

運作原理

原理

舉個例子來說迷,如果我的需求是「預定一間旅館的房間」,那麼我會在我的預定程序中找到「檢查剩餘空房間」、「計算住宿價格」、「更新資料庫」等邏輯,而 Transactin Script 則是將這些邏輯封裝在預定房間的程序中。

位置與分層

Transactin Script 放置的位置取決於你的軟體分層,不過作者推薦你盡量的將 Transactin Script 與其他分層隔離,另外不要讓你的 Transactin Script 去呼叫任何來自展示層的邏輯,這會讓你在修改和測試 Transactin Script 變得困難。

實踐方式

你可以透過兩種方式將 Transactin Script 組織到類別中。

Transactin Script 類別

你可以組織一個類別,包含多個 Transactin Script ,其中這些 Transactin Script 是有相同主題的。

Command Pattern

另外一種方式是透過設計模式中的「命令模式」(Command Pattern)

使用時機

優勢

Transactin Script 最大的好處就是贏在他的簡單性,對只有少量邏輯的應用程式來說,它非常好理解。

劣勢

但隨著商業模式變得複雜,使用這個模式要保持良好的設計狀態就會變得很困難。這邊要注意一個問題,有些程式邏輯在很多交易中都會使用到,這點會讓整體的重複變得很多。

改善的方向

而將這些重複邏輯仔細地做分解可以解決這個問題,而更複雜的商業領域可能就會需要建置一個 Domain Model (領域模型,ch 9.2)來達成更好的設計。

範例:收入確認

針對這個模式,書中有給一個在「收入確認」上的範例情境。

收入確認問題

收入確認是商業系統中常見的問題,有的時候商業上賣出東西可能是一次付清也可能是分期付款,而分期付款的帳面又不能算是一次入帳,他可能平分成好幾個月的金額,然後每個月入帳一些。

Code Example

書上原本會利用這個情境使用兩個範例作為說明,這邊為了好做說明,筆者會將整理簡化,只用一個範例來說明。

底下我們將會製作一個 Transactin Script 來計算,合約在「某個日期」以前已經確認的收款金額

以下是資料表設計

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

left to right direction

''''''''' Tables '''''''''

class products << (T,#ADD1B2) >> {
id : int
--
name : string
}

class contracts << (T,#ADD1B2) >> {
id : int
--
product_id : int
--
revenue : int
}

class revenue_recognitions << (T,#ADD1B2) >> {
id : int
--
contract_id : int
--
amount : int
--
recognized_at : timestamp
}

''''''''' Join Relations '''''''''

products::id "1"--"*" contracts::product_id
contracts::id "1"--"*" revenue_recognitions::contract_id