https://blog.p1ass.com/posts/directory-structure/

モノリシックなプロジェクトにおいて、トップレベルのディレクトリ構成が異なる 2 つのディレクトリ構成を考え、それらの違いは何で、どちらが優れているか?という問いについて考えた。そして、「複雑な概念をトップレベルのディレクトリ構成にした方が良いのでは?」という結論に落ち着いた話をする。

はじまり

ちょっとしたシナリオを想像してみよう。

プロジェクト立ち上げ期

「最近のトレンドはレイヤードアーキテクチャだ!」

そう言って、プロジェクトはスタートした。

.
├── application
│  ├── xxx_usecase.go
│  ├── xxx_repository.go
│  ├── yyy_usecase.go
│  └── yyy_repository.go
├── domain
│  ├── xxx.go
│  └── yyy.go
├── infrastructure
│  └── xxx_repository_impl.go
└── presentation
│  ├── xxx_handler.go
│  └── yyy_handler.go

ドメインの成長期

プロジェクト立ち上げ期に作ったアーキテクチャは、依存関係を把握するのに役に立っていた。 ビジネスが成長するにつれて、ドメインはどんどん複雑になっていくが、どのディレクトリにコードを置けば良いのか迷う必要がない。

よく出来たディレクトリ構成だと思っていたが、新しくプロジェクトに参加した人からこんなコメントをもらった。

「機能間の繋がりがいまいち分からない。」

各レイヤーのディレクトリの下にサブディレクトリを切っていなかったため、レイヤーに関係する全てのファイルが 1 つのディレクトリ置かれていた。 相互に呼び出されることない全く異なるドメインのファイルが同じディレクトリに置かれており、認知負荷が高まっていた。

.
├── application
│  ├── xxx_usecase.go
│  ├── xxx_repository.go
│  ├── yyy_usecase.go
│  ├── yyy_repository.go
│  └── # ここに数十、数百のファイルが置かれていた
├── domain
│  ├── xxx.go
│  ├── xxx_foo.go
│  ├── xxx_bar.go
│  ├── yyy.go
│  ├── yyy_hoge.go
│  ├── yyy_fuga.go
│  └── # ここに数十、数百のファイルが置かれていた
├── infrastructure
│  ├── xxx_repository_impl.go
│  └── # ここに数十、数百のファイルが置かれていた
└── presentation
│  ├── xxx_handler.go
│  └── yyy_handler.go
│  └── # ここに数十、数百のファイルが置かれていた

ずっとプロダクトに携わっている人間にとっては、ほぼ全ての機能を把握しているので、特に困らない。 しかし、新しいメンバーにとっては必ずしもそうではない。

このような状況の対処するために、DDD の文脈での「境界づけられたコンテキスト」ごとに、サブディレクトリを切ることにした。

.
├── application
│  ├── xxx
│  │  ├── usecase.go
│  │  ├── repository.go
│  │  └── # そこまで多くないファイル数
│  └── yyy
│     ├── usecase.go
│     ├── repository.go
│     └── # そこまで多くないファイル数
├── domain
│  ├── xxx
│  │  ├── foo.go
│  │  ├── bar.go
│  │  └── # そこまで多くないファイル数
│  └── yyy
│     ├── hoge.go
│     ├── fuga.go
│     └── # そこまで多くないファイル数
├── infrastructure # 省略
└── presentation #省略

これにより、