博客 / 詳情

返回

為什麼要先規劃目錄結構

剛開始寫 Go 項目的時候,我對目錄結構這件事格外重視。對於剛入門的人來説,開發過程中幾乎每件事情都是第一次:

  • 全局配置怎麼放?
  • 數據庫連接怎麼初始化?
  • Model 怎麼設計?
  • 路由怎麼組織?

每一個點都能讓人迷茫。

相比之下,像 Java 的 Spring Boot 或 PHP 的 Laravel 都會給你一套“默認結構”,至少能讓你知道應該往哪裏放東西。

而 Go 更自由,沒有強迫你必須怎麼做。對老手是好事,對新手卻可能會踩坑。

我的經驗是:

合理的目錄結構 = 清晰的思路 + 舒適的開發體驗

規劃好結構之後,你可以把問題拆開逐個去實現,而不是一上來就面對一坨混亂的代碼。


我的 Go 項目目錄結構(Gin 示例)

下面是我常用的目錄結構,適合大多數中小型 Web 項目:

.
├── cmd/              # 項目入口目錄
│   └── main.go       # 主程序入口
├── internal/         # 私有代碼目錄
│   ├── dto/          # 結構體定義目錄
│   ├── handler/      # HTTP處理器(等同於Controller)
│   ├── model/        # 數據模型
│   ├── repository/   # 數據模型訪問層
│   ├── router/       # 路由
│   └── service/      # 業務邏輯層
├── pkg/              # 可被外部引用的包
│   ├── config/       # 配置
│   ├── i18n/         # 國際化
│   ├── jwt/          # jwt
│   ├── middleware/   # 中間件
│   └── utils/        # 工具函數
├── api/              # API文檔(Swagger)
│   └── swagger.json
├── scripts/          # 構建、部署腳本目錄
├── go.mod
├── LICENSE
├── Makefile          # 自動化腳本説明書
└── README.md

cmd/:項目入口

cmd 存放整個項目的入口程序。

通常項目只有一個:

cmd/
└── main.go

如果未來拆成多個服務(如 API + Worker),結構可以擴展成:

cmd/
├── api/
│   └── main.go
├── worker/
│   └── main.go

這樣多服務更好管理。


internal/:項目私有代碼

internal​ 是 Go 官方定義的 ​私有代碼機制:這裏的包只能本項目引用,外部無法導入。

我會把它拆成幾個層次,職責分明:

internal/
├── dto/          # 請求/響應結構體
├── handler/      # HTTP 層
├── service/      # 業務邏輯層
├── repository/   # 數據訪問層
├── model/        # 數據模型
└── router/       # 路由註冊

調用鏈是單向的:

Handler → Service → Repository → Model

下面簡單説一下每層負責什麼:

  • Handler:接收/解析請求,參數校驗,調用 Service
  • Service:業務邏輯處理
  • Repository:數據庫讀寫(純 CRUD,不寫業務)
  • Model:數據庫結構體
  • DTO:請求/響應結構(隔離 Model)
  • Router:註冊路由,綁定 Handler

這種分層結構很適合 Go,也比 PHP 那種“一個 controller 幹到底”的寫法更好維護。

另外,Go 的一個特點是:

同一個 package 下多個 ​.go​文件對編譯器來説等同於同一個文件。

所以可以自由地按模塊拆成多個 user.go​、order.go,對程序來説他們直接就是一個文件不會有任何影響,但分開之後代碼的可讀性會極大的提高。

如果你有其他面嚮對象語言的經驗,Go會帶來全新的編程體驗。核心的思維轉變可歸納為四點:

  1. 忘掉"類" → 記住"結構體+方法"
  2. 忘掉"繼承" → 使用"組合+接口"
  3. 忘掉"設計模式套用" → 關注"解決問題"
  4. 接受顯式錯誤處理 → 不再有try-catch

pkg/:可複用的公共包

pkg 用來放可被其他項目引用的通用模塊,例如:

pkg/
├── config/
├── i18n/
├── jwt/
├── middleware/
└── utils/

如果只是給當前項目用,不需要放在 pkg​,儘量歸到 internal

另外也建議不要堆一個“大 utils”,按功能拆分更容易維護。


api/:API 文檔

這裏一般放 Swagger / OpenAPI 的定義文件(JSON/YAML)。

用這些工具來管理接口文檔可以:

  • 自動生成文檔
  • 保持前後端對齊

對於多人協作非常有用。


Makefile:常用命令的“快捷鍵”

我一般會把常用命令寫進 Makefile,比如:

run:
    go run cmd/main.go

build:
    go build -o bin/app cmd/main.go

test:
    go test ./...

Makefile 是個好東西,你可以把各種項目會用到的命令像清單一樣列出來。

如果你有心思,甚至可以去做一個 help 命令來告訴其他人都有什麼命令

help:
    @echo "可用指令:"
    @echo "  make deps          # 安裝 / 更新 Go 依賴"
    @echo "  make fmt           # 統一格式化後端 Go 代碼"
    @echo "  make test          # 執行全部 Go 單元測試"

對新同事非常友好,哪怕不瞭解項目,也可以通過閲讀 Makefile 快速上手項目。


總結

對我來説,一旦目錄結構定下來,剩下的基本就像做“填空題”一樣:

  • 中間件怎麼寫
  • JWT 怎麼做
  • 數據庫要建哪些表
  • Handler / Service / Repository 各自實現哪些邏輯

這些都能一塊一塊穩穩推進。

Go 社區裏沒有唯一正確的結構,但這套分層思路對新手來説非常友好,也足夠應對大部分項目。

如果你正在準備寫一個 Go 項目,希望這套結構能幫你少踩一些坑,也讓你的項目更容易維護。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.