---
title: "案例說明 - Clean Architecture in Go"
date: 2025-01-24T00:00:00+08:00
publishDate: 2025-01-24T00:00:00+08:00
lastmod: 2024-10-07T20:05:43+08:00
tags: ["Golang","Clean Architecture","架構","經驗"]
series: "clean-architecture-in-go"
toc: true
permalink: "https://blog.aotoki.me/posts/2025/01/24/clean-architecture-in-go-example-case/"
language: "zh-tw"
---


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

<!--more-->

## 訂單資訊{#order-information}

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

```go
type Order struct {
	id    string
	name  string
	items []Item
	state string
}
```

大致上是類似上述的感覺，現階段只是以 Golang 來呈現概念，並不會是我們實際上實作的程式碼。這個訂單設計是一個很簡單的結構並不複雜，然而想要應用 Clean Architecture 後面會有許多需要考量到的細節。

## 訂單品項{#order-items}

除了訂單資訊外，我們也希望有一些品項的資訊保存在裡面，因此會紀錄項目、價格，為了維持功能簡單，這裡選擇不關聯某個商品編號。

```go
type Item struct {
	name      string
	quantity  int
	unitPrice float64
}
```

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

## 功能需求{#requirement}

最後，我們使用 BDD（Behavior-Driven Development）的方式來描述在這個訂單服務中預期看到的功能運作。

```gherkin
Feature: 訂單服務
	Scenario: 可以建立一筆新的訂單
	  When 建立訂單
	  """
	  {
	    "name": "蒼時弦也"
	  }
	  """
	  And 加入以下品項
	  | name     | quantity | unitPrice |
	  | 可口可樂   | 1        | 35        |
	  | 明治巧克力 | 2        |  45       |
	  And 送出訂單
	  Then 我可以看到回傳中 ".name" 是 "蒼時弦也"
	  And 我可以看到回傳中 ".subtotal" 是 125
	  And 我可以看到回傳中 ".items[0].name" 是 "可口可樂"
	  # ...

	Scenario: 我可以查詢某筆訂單
	  Given 有一筆訂單存在
	  """
	  {
		  "id": "f9c81702-3fe9-4382-afa1-e03480c1a206",
		  "name": "蒼時弦也",
		  "items": [
		    { "name": "可口可樂", "amount": 1, "unitPrice": 45 }
		  ]
	  }
	  """
	  When 查詢訂單 "f9c81702-3fe9-4382-afa1-e03480c1a206"
	  Then 我可以看到回傳中 ".name" 是 "蒼時弦也"
	  And 我可以看到回傳中 ".subtotal" 是 45
	  And 我可以看到回傳中 ".items[0].name" 是 "可口可樂"
	  # ...
```

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

