案例說明 - Clean Architecture in Go
這一系列會延續以往的做法,以實際的案例來說明。這一次我們會選擇以「訂單服務」作為例子,然而並不是單純的訂單服務,是一個會針對個資加密處理的服務。
訂單資訊
作為一個訂單系統,我們勢必會須要去維護訂單的基本資訊,我們先假設會需要下訂者的名字(個資)以及購買的品項。
1type Order struct {
2 id string
3 name string
4 items []Item
5 state string
6}
大致上是類似上述的感覺,現階段只是以 Golang 來呈現概念,並不會是我們實際上實作的程式碼。這個訂單設計是一個很簡單的結構並不複雜,然而想要應用 Clean Architecture 後面會有許多需要考量到的細節。
訂單品項
除了訂單資訊外,我們也希望有一些品項的資訊保存在裡面,因此會紀錄項目、價格,為了維持功能簡單,這裡選擇不關聯某個商品編號。
1type Item struct {
2 name string
3 quantity int
4 unitPrice float64
5}
我在這裡設計了 amount
和 unitPrice
的資訊,在這個案例中我們還會針對訂單的總金額計算,因此預期品項中會出現價格和數量的資訊。
功能需求
最後,我們使用 BDD(Behavior-Driven Development)的方式來描述在這個訂單服務中預期看到的功能運作。
1Feature: 訂單服務
2 Scenario: 可以建立一筆新的訂單
3 When 建立訂單
4 """
5 {
6 "name": "蒼時弦也"
7 }
8 """
9 And 加入以下品項
10 | name | quantity | unitPrice |
11 | 可口可樂 | 1 | 35 |
12 | 明治巧克力 | 2 | 45 |
13 And 送出訂單
14 Then 我可以看到回傳中 ".name" 是 "蒼時弦也"
15 And 我可以看到回傳中 ".subtotal" 是 125
16 And 我可以看到回傳中 ".items[0].name" 是 "可口可樂"
17 # ...
18
19 Scenario: 我可以查詢某筆訂單
20 Given 有一筆訂單存在
21 """
22 {
23 "id": "f9c81702-3fe9-4382-afa1-e03480c1a206",
24 "name": "蒼時弦也",
25 "items": [
26 { "name": "可口可樂", "amount": 1, "unitPrice": 45 }
27 ]
28 }
29 """
30 When 查詢訂單 "f9c81702-3fe9-4382-afa1-e03480c1a206"
31 Then 我可以看到回傳中 ".name" 是 "蒼時弦也"
32 And 我可以看到回傳中 ".subtotal" 是 45
33 And 我可以看到回傳中 ".items[0].name" 是 "可口可樂"
34 # ...
看起來並不複雜,然而這個處理中我們還需要思考「姓名」的加密處理,雖然在使用者端看不出來有被加密,但是在後端是有處理的,我們會在後續的實作過程稍微修正上述的測試案例,來滿足加密機制的實現。
如果對這篇文章有興趣,可以透過以下連結繼續閱讀這系列的其他文章。
- 連載介紹 - Clean Architecture in Go
- 目標設定 - Clean Architecture in Go
- wire 的依賴注入 - Clean Architecture in Go
- 案例說明 - Clean Architecture in Go