蒼時弦也
蒼時弦也
資深軟體工程師
發表於

案例說明 - Clean Architecture in Go

這篇文章是 Clean Architecture in Go 系列的一部分,你可以透過 Leanpub 提前閱讀內容。

這一系列會延續以往的做法,以實際的案例來說明。這一次我們會選擇以「訂單服務」作為例子,然而並不是單純的訂單服務,是一個會針對個資加密處理的服務。

訂單資訊

作為一個訂單系統,我們勢必會須要去維護訂單的基本資訊,我們先假設會需要下訂者的名字(個資)以及購買的品項。

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}

我在這裡設計了 amountunitPrice 的資訊,在這個案例中我們還會針對訂單的總金額計算,因此預期品項中會出現價格和數量的資訊。

功能需求

最後,我們使用 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	  # ...

看起來並不複雜,然而這個處理中我們還需要思考「姓名」的加密處理,雖然在使用者端看不出來有被加密,但是在後端是有處理的,我們會在後續的實作過程稍微修正上述的測試案例,來滿足加密機制的實現。