Modular Monolith + Vertical SliceはOwnership境界と変更単位を別スケールで持つ
Modular MonolithとVertical Sliceは競合するArchitecture Styleというより、異なる粒度の問題を解く組み合わせとして考えられる。
- Module: capability/domainのownership boundary
- Vertical Slice: Module内のuse case / Operationごとの変更単位
例えばDocument Moduleが CreateDocument、SearchDocuments、ShareDocument を公開し、それぞれをsliceとして局所化する。外部ModuleはDocument ModuleのPublic APIだけを見る。内部では各Operationが必要なvalidationやdata accessを最短経路で組み立てる。
document/ # Module boundary
api/
create_document/ # Vertical Slice
search_documents/
share_document/
internal-domain/
この構成は、Spring Modulithが提供するPublic/Internal/Allowed Dependencyのようなmodule governanceと、Vertical Sliceの「change axisに沿ってまとめる」考え方を同時に使う発想である。Moduleをまたぐ依存は厳しく、Module内部のsliceは必要以上にlayer化しない。
利点は、Application全体を小さなOperation folderの平面にせず、かつ各Module内部をController/Service/Repositoryの水平Layerへ分散させすぎないことにある。Module BoundaryはAI Coding AgentのContext Boundaryとしても機能しうる の観点でも、「まずModuleを特定し、その中でSliceを特定する」という二段階localizationが可能になる。
反論として、規模が小さいうちはModuleとSliceの二重分類が冗長になる。ModuleごとのPublic APIを通すために単純な隣接機能まで迂回すると、localityを損なうこともある。境界は組織図ではなく、変更頻度・語彙・transaction boundary・dependency directionなどから決めるべきである。