TL;DR
- 責務分離の崩壊は「SRP の誤解」「境界コンテキストの曖昧さ」「AI生成コードの最短経路バイアス」の3点で起きる。
- AI は「動くコード」を最優先するので、責務境界を越えるインポートを気軽に入れる。
- 設計レビューで検知するには 依存グラフの可視化 と インポート方向のルール化 が効く。
はじめに
この記事はシリーズ「技術選定で後悔しないための判断基準」の 分割の原則論 の深掘りです。 👉 技術選定で後悔しないための判断基準 流行との距離を測る
AI コーディングエージェントが普及してから、責務分離の崩壊速度が上がっています。理由は明確で、AI は「動くコード」を優先するので、責務を跨いだ直接呼び出しを平気で入れてくるからです。
1. 責務分離の原則(SRP / 境界コンテキスト)
SRP の本当の意味
SRP(Single Responsibility Principle)は「1クラスに1メソッド」ではなく、「1つの理由でしか変更されない」という原則です。言い換えると「同じアクター(ステークホルダー)からの変更要求でしか修正されない」こと。User と Admin から同時に変更要求が来るクラスは SRP 違反です。
境界コンテキストで境界を決める
境界はコードの美しさではなく業務ドメインの境界で決めます。同じ「注文」でも、販売ドメインと物流ドメインでは責務が違います。境界を跨ぐ時は明示的な変換(DTO / イベント)を通し、共有の可変状態を避けます。
レイヤー設計の原則
典型的な3層(presentation / application / domain)では、依存方向を 一方向 に揃えます。domain が他層を知らない状態を維持できれば、テストも設計判断も独立します。逆に domain が presentation を import した瞬間、その層は機能していません。
2. AI生成コードで崩壊する理由
AI は「最短経路で動くコード」を好みます。これは責務分離にとって相性が悪い:
- 手軽な import を選ぶ:
domain/user.tsからlib/http.tsを直接呼んで外部API叩く、のような責務越境 - ファイル数を最小化する: 1ファイルに複数の責務を詰める
- 既存パターンを無視する: repo 側に
UserRepositoryがあるのに、新コードで直接 DB を触る
これらは人間のレビューで検知できますが、レビューが追いつかない速度で生成されるのが今の課題です。AI時代のレビュー体制そのものは AIレビューと人間レビューの境界設計 も合わせて考える領域です。
3. 設計レビューで崩壊を検知する
検知方法は3つ。
依存グラフの可視化
depcheck / dependency-cruiser / madge 等で依存グラフを生成し、CI で前回比の差分を可視化。新たに引かれた依存のうち、下位層→上位層 の方向のものはレビュー必須にします。
インポート方向のルール化
// .dependency-cruiser.json 抜粋
{
"forbidden": [
{
"name": "no-domain-to-infra",
"from": { "path": "^src/domain" },
"to": { "path": "^src/infra" }
}
]
}
CI でこのルールを検査し、違反したPRは自動的に block。AI 生成コードでもこれで止まります。関連する権限設計として、AI エージェント自体の振る舞いを制限する MCPで"運転席と作業者"を分離して事故率を下げる も参照。
PR テンプレートに依存差分チェック欄
PR テンプレートに「新規に引かれた依存レイヤーを跨ぐものの有無」をチェックボックスで追加。自己申告が形式化するだけでも検知漏れが減ります。
速度と品質のトレードオフ判断は、個別レビューではなくチームの意思決定フレームとして持っておくのが有効です。
まとめ
責務分離は AI 時代に最初に崩壊する層です。SRP・境界コンテキスト・依存方向の3点を抑え、依存グラフの自動検査で崩壊を止めましょう。
全体像に戻る: 親記事はこちら
技術選定の運用フレームは Technology Radar の作り方|30分会議テンプレ付 を参照(Adopt / Trial / Assess / Hold で月次運用に乗せる)。
