パッケージ構成
パッケージ構成は、大まかに分けて3種類...
One Package
- Repository自体を単一のパッケージとみなす
- Coverageが取りやすい
- Libraryなど、簡素な構成で済むものに向いている
. ├── ctx.go ├── debug.go ├── error.go ├── handler.go ├── handler_func.go ├── jsonrpc.go ├── method.go └── parse.go
Flat Package
- 各パッケージの責務を明確にし、分割を行う
- 機能ごとに分割しているイメージ
- Go言語の標準パッケージの構成に親しい考え方
- 階層を掘ったとしても、2階層ぐらいで落ち着く
- パッケージの責務を明確にし、お互いに疎結合を心がける
- Micro Serviceや、Middlewareなどに向いている
. ├── ctx │ └── ctx.go ├── debug │ └── debug.go ├── error │ └── error.go ├── handler │ ├── handler.go │ └── handler_func.go ├── jsonrpc.go ├── method │ └── method.go └── parse └── parse.go
Multiple Packages
. ├── controller │ ├── debug │ │ └── debug.go │ └── handler.go ├── jsonrpc.go ├── model │ ├── ctx │ │ └── ctx.go │ ├── error │ │ └── error.go │ ├── marshal │ │ └── unmarshal.go │ └── method │ └── method.go └── view └── index.html.tpl
DDD(ドメイン駆動設計) Domain-Driven Design
- 顧客と開発者が業務を戦略的に理解し、共通の言葉を使いながらシステムを発展させる手法
- DDDでは大規模な1つのシステムとデータベースで構築するのではなく、業務にとって適切な独立したシステムに分割する
レイヤードアーキテクチャ
- ドメインロジックと、それ以外(DBやViewなど)を切り離すのが目的
Lightweight DDD
src/ └── myapp ├── application ├── domain ├── infrastructure ├── interfaces └── library
4つのLayerで構成
- Application
- Domain
- Infrastructure
- Interface(s)
Application Layer
- Domain layerの処理をまとめInterface Layerに提供
- Flat Packagesの思想でパッケージ分割
- interパッケージに活用し、共通ロジックを隠蔽
- Domain Layer
- Domain Layerは、他Layerには依存しない
- Entityや、Enum,Interfaceを提供
- Infrastructure Layer
- GAEのライブラリをWrap
- 基礎的な処理を保持
- Logging
- Validation Rule
- World Filtering
- Value Get/Set in Context
- Persistence
- Interface Layer
- JSON-RPCのHandler群
- Search.FindProducなど
- Original Error定義
- 32044:Not Foundなど
- Interceptor群
- Contextに色々詰める
- Action Loggerなど
- その他
- Startup処理、状態取得
- JSON-RPCのHandler群
最適なパッケージ構成
相互参照せずに快適に開発を進められるパッケージ構成を見つけるのは難しい
第1ケース
プロジェクトルートに展開する
. ├── db.go ├── errors.go ├── handler.go ├── main.go └── model.go
概要
- ほぼ全てのファイルをプロジェクトルートに展開するやり方、mainパッケージに集約する
- utlity的な共通処理も、構造体もinterfaceもその実装も、全て同じ階層にあれば、パッケージを切る必要がない
特徴
- CLIツールや小さめのサーバー、あるいは小さめのパッケージなどには適している
デメリット
- 中規模以上のAPIサーバーを用意するとなると厳しい
- 20個以上とかファイルが乱立すると分かりにくくなる
第二ケース
MVC
. ├── main.go ├── clients ├── config ├── controllers ├── models └── views
. ├── main.go ├── clients ├── config ├── controllers ├── models ├── article └── user └── views
- リソースごとにパッケージを区切りたくなるが、これでは大体相互参照の問題にぶつかる
article.goとuser.goなど、構造体やそれに付随する実装を全てmodelsディレクトリ直下に展開するという流れがある
小さめのAPIなら許容できなくいが、主要APIとして利用されるサーバーコードを書くときはリソースが多くなり、goのソースコードのファイルが多くなる