スキーマでアーキテクチャを縛る ── 人間とAIを同じルールで動かす

はじめに
はじめに
こんにちは、ZOZOTOWN開発1部iOSブロックの@kitasukeです。
こんにちは、ZOZOTOWN開発1部iOSブロックの@kitasukeです。
前回の記事「ZOZOTOWN iOS のアーキテクチャとチームの進化」では、MVCからMVVM、そしてMVVM + Repositoryへのアーキテクチャ進化を取り上げました。あわせて、レビュー文化をチームに根づかせてきた3年間も振り返っています。
前回の記事「ZOZOTOWN iOS のアーキテクチャとチームの進化」では、MVCからMVVM、そしてMVVM + Repositoryへのアーキテクチャ進化を取り上げました。あわせて、レビュー文化をチームに根づかせてきた3年間も振り返っています。
ただ、アーキテクチャを文章で定義しても、書き手によって命名や責務分割はぶれが生じますし、AIに任せると過去の望ましくない実装パターンまで律儀に再現されます。ドキュメントによる「努力目標」では、アーキテクチャは守りきれません。
ただ、アーキテクチャを文章で定義しても、書き手によって命名や責務分割はぶれが生じますし、AIに任せると過去の望ましくない実装パターンまで律儀に再現されます。ドキュメントによる「努力目標」では、アーキテクチャは守りきれません。
そこで発想を逆にしました。アーキテクチャを「守るべきルール」ではなく、構造化されたスキーマとして定義し、人間とAIの双方がそれに従うしかない形にします。Swiftの型システムがコンパイル時に不正を弾くのと同じ発想を、アーキテクチャのレイヤーにスキーマという形で持ち込みます。それが本記事で紹介する**「スキーマでアーキテクチャを縛る」アプローチ**です。副産物として、設計からコードを自動生成するパイプラインも動いています。
そこで発想を逆にしました。アーキテクチャを「守るべきルール」ではなく、構造化されたスキーマとして定義し、人間とAIの双方がそれに従うしかない形にします。Swiftの型システムがコンパイル時に不正を弾くのと同じ発想を、アーキテクチャのレイヤーにスキーマという形で持ち込みます。それが本記事で紹介する**「スキーマでアーキテクチャを縛る」アプローチ**です。副産物として、設計からコードを自動生成するパイプラインも動いています。
目次
目次
どんなスキーマを定義したのか
どんなスキーマを定義したのか
全体像はこうなっています。
全体像はこうなっています。
仕様書 (Confluence) / デザイン (Figma) / 既存コード
│
▼ /architecture
┌─────────────────────┐
│ 設計 YAML │ ←── AI / Codegen 向け
│ Human Doc (Markdown) │ ←── 人間向けレビュー資料
└─────────────────────┘
│
▼(人間がレビュー・編集)
│
▼ /codegen
Swift コード一式
↑ 全工程でガイドラインとテンプレートが参照される
土台となっているのが、チームで整備した 2つのドキュメント です。
土台となっているのが、チームで整備した 2つのドキュメント です。
architecture-guidelines.md— 各コンポーネントのスキーマ(何が正しいか)architecture-guidelines.md— 各コンポーネントのスキーマ(何が正しいか)architecture-templates.md— スキーマからSwiftを導出するテンプレート(どう書くか)architecture-templates.md— スキーマからSwiftを導出するテンプレート(どう書くか)
architecture-guidelines.md — コンポーネントをスキーマで縛る
architecture-guidelines.md — コンポーネントをスキーマで縛る
各コンポーネント(ViewModel、Repository、Translatorなど)を、型・依存・命名・必須ルール・禁止パターンなどのフィールドで厳密に定義しています。たとえばViewModelのスキーマは次のとおりです。
各コンポーネント(ViewModel、Repository、Translatorなど)を、型・依存・命名・必須ルール・禁止パターンなどのフィールドで厳密に定義しています。たとえばViewModelのスキーマは次のとおりです。
### ViewModel
- type: \`@MainActor final class\`
- imports: [Foun...