高凝集と疎結合、純粋なドメイン層。AIの力を最大限引き出す設計思想と、それを破らせない仕組み(10分バージョン)
by
株式会社カミナシ
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
⾼凝集と疎結合、純粋なドメイン層 AIの⼒を最⼤限引き出す設計思想と それを破らせない仕組み (10分 ver) TSKaigi Mashup Kansai
Slide 2
Slide 2 text
⾃⼰紹介 ● 名前: Shimmy ● 所属: 株式会社カミナシ ○ ソフトウェアエンジニア ○ カミナシで新規プロダクトを開発中 ○ エンジニアは私1⼈、Claude Codeを活⽤している ● その他: ○ 最近は三国志のゲームに時間を取られています ○ AIのお陰で個⼈開発にまた⽕がついて、ゴリゴリコードを書いてます (AIが)
Slide 3
Slide 3 text
今⽇話すこと 1. AIの⼒を最⼤限引き出す設計 2. その設計をAIに破らせない仕組み
Slide 4
Slide 4 text
AIの⼒を最⼤限 引き出す設計
Slide 5
Slide 5 text
条件1: 関⼼の分離 関⼼事で分ける ● ある機能を修正したいとき、修正したい箇所がまとまって いると扱いやすい ● ファイルがすべて1ディレクトリの中にあるのでAIのコン テキストに載せやすい ● 並列にAI開発しても関⼼ごと別に分ければコンフリクトし にくい
Slide 6
Slide 6 text
条件2: テスト容易性 ● 純粋関数はテストしやすい ● 出⼒値ベーステスト: Inputを⼊れてOutputを検証する ● モック不要でAIに書かせやすい ● テスト実⾏が速い
Slide 7
Slide 7 text
条件3: 依存⽅向の決定 層ごとに「何に依存してよいか」が決まっている
Slide 8
Slide 8 text
設計を守る3つのルール
Slide 9
Slide 9 text
ルール1: 純粋なドメイン層 domain/からinfrastructure/やserver/をimportしてはいけ ない ● domain層はどの層にも依存しない ● 純粋な関数と型だけの世界 ● drizzle-ormなどI/O系ライブラリのimportも禁⽌
Slide 10
Slide 10 text
ルール1: 純粋なドメイン層 実際の構成
Slide 11
Slide 11 text
ルール2: Feature間の疎結合 あるfeatureから別のfeatureを直接importしてはいけない ● 共有したいロジックはshared/に置く ● feature同⼠の連携が必要な場合は routes/層で組み⽴てる ● featureは互いの存在を知らない
Slide 12
Slide 12 text
ルール3: Public API境界 routes/からfeatures/を参照する際はindex.ts経由のみ ● domain/やserver/など内部ディレクトリを直接参照して はいけない ● index.tsで外部に公開したいものだけをexport
Slide 13
Slide 13 text
破られるルールから 破れないガードレールに
Slide 14
Slide 14 text
なぜ「ルールを教える」だけでは⾜りないのか AIの出⼒速度に⼈間のレビューが追いつかない ● AIはすごい勢いでコードを書く ● レビュアーがボトルネックになる ● 何度も同じ指摘をしたくない
Slide 15
Slide 15 text
ガードレールとしての条件 ● 確定的であること ○ AGENT.mdは確率的 → 確定的なシステムが必要 ● 速くフィードバックできること(Shift Left) ○ AIの試⾏錯誤ループの中でフィードバックしたい
Slide 16
Slide 16 text
静的解析 dependency-cruiser
Slide 17
Slide 17 text
dependency-cruiserで設計を強制する import⽂を静的解析して依存関係のルール違反を検出する ツール ● 設計思想をdependency-cruiserのルールとする ● 新規プロダクトでは12個のルールを定義
Slide 18
Slide 18 text
ルール定義①: 純粋なドメイン層 domain/からinfrastructure/やserver/をimportする とエラー
Slide 19
Slide 19 text
ルール定義②: Feature間の疎結合 同⼀feature内はOK。別featureを直接importするとエラー
Slide 20
Slide 20 text
ルール定義③: Public API境界 index.tsを通さずにfeature内部を参照するとエラー
Slide 21
Slide 21 text
その他の静的解析ツール ● knip: 未使⽤コードを検出 ○ AI実装で⽣まれる未使⽤exportやファイルを⾃動検出 ● Biome: コード品質を統⼀ ○ any型禁⽌、⾮nullアサーション禁⽌、awaitされていないPromise検出
Slide 22
Slide 22 text
Git hooksで統合する
Slide 23
Slide 23 text
lefthook: コミット前に⾃動で弾く ● pre-commit: Biomeのチェック + dependency-cruiser ● pre-push: 型チェック + knip + テスト
Slide 24
Slide 24 text
開発フロー アウトプットではなく、プロセスを信頼できるものにする 1. AIにコードを書かせる 2. git commit a. Biome + dependency-cruiser が⾛る b. 設計違反があればエラー c. → AIが⾃動修正 3. git push a. → 型チェック + knip + テスト が⾛る
Slide 25
Slide 25 text
まとめ
Slide 26
Slide 26 text
3つ設計思想を振り返る ● 関⼼の分離 ○ Feature内は⾼凝集、Feature間は疎結合 ● 依存⽅向の決定 ○ domain層は純粋に。repository, serverから利⽤ ● テスト容易性 ○ テストしやすい関数に。
Slide 27
Slide 27 text
設計思想をコードで強制する dependency-cruiserで設計思想をガードレールに ● domain層から他の層をimportしたらエラー ● 別featureを直接importしたらエラー ● index.tsを通さずfeature内部を参照したらエラー knip + Biome も活⽤し、lefthooksで確定的に実⾏
Slide 28
Slide 28 text
設計思想を 破られるルールから 破れないガードレールに
Slide 29
Slide 29 text
株式会社カミナシ https://kaminashi.jp