TITLE
クリーンアーキテクチャで安心してはいけない(レイヤードアーキテクチャ + Port設計という選択肢)

先日公開した「ドメイン駆動設計におけるアーキテクチャの比較(レイヤードアーキテクチャ vs クリーンアーキテクチャ)」について、 AI(Claude - Fable 5)を壁打ち相手として、その内容を検証する議論を行いました。

議論は当初、記事の評価から始まりましたが、 「テスト容易性に差はあるのか」「構造規則は何を担保するのか」「成熟したエンジニアは不可欠なのか」と論点が展開していき、 最終的に、当初の想定よりも強い結論に到達しました。すなわち、

クリーンアーキテクチャを採用したからといって、設計品質は何も担保されない。 それどころか、クリーンアーキテクチャが固有に提供していた価値の多くは、現在では他の手段で代替可能になっており、 残るのは「凝集の喪失」という恒常的なコストである。

本稿では、この結論に至った議論の過程そのものを紹介します。 結論だけでなく過程を紹介するのは、途中でAI側の主張が何度も崩され、修正されていく流れにこそ、 訴求の根拠としての価値が詰まっていると考えるためです。

先に結論

  • クリーンアーキテクチャの構造規則が担保するのは配線品質(依存方向、境界の形式)であり、設計品質(ユースケースの切り出し、集約の設計)ではない
  • 配線品質の担保は、現在ではArchUnitなどの防止層により、アーキテクチャ非依存で実現可能である
  • ユースケースを適切な粒度に切り出せないチームは、どちらのアーキテクチャを採用しても設計品質を担保できない。つまり両者の実質的な習熟度要件は同等である
  • 習熟度要件が同等である以上、比較は純粋なコスト対効果の勝負となり、クリーンアーキテクチャは「1ユースケース1クラスによるコンテキスト凝集の喪失(アプリケーション層版ドメイン貧血症)」という恒常的なコストを、対価なく払い続けることになる
  • ただし、非ドメイン集合の永続化(ファイル入出力・Email送信・外部API呼び出し)に対するPort設計は、クリーンアーキテクチャが生んだ本当に新しい価値であり、これはレイヤードアーキテクチャに選択的に移植する価値がある

したがって推奨は、「クリーンアーキテクチャの全面採用」でも「純粋なレイヤードアーキテクチャへの回帰」でもなく、 レイヤードアーキテクチャをベースに、Port設計のみを選択的に取り込んだハイブリッド構成です。

src/
 +- application/
 |   +- (ApplicationServiceはユースケースをメソッドとして表現します)
 |   +- port/
 |       +- (ここにドメイン以外の永続化を担当するリポジトリインターフェースが配置されます)
 +- domain/
 |   +- (ここにドメインの集合を操作するリポジトリインターフェースが配置されます)
 +- infrastructure/
 |   +- jdbc/
 |   +- jpa/
 +- presentation/

「クリーンアーキテクチャを採用しているから大丈夫」という安心は、 担保されていないもの(設計品質)を担保されていると誤認する、最も高くつく安心です。 以下、この結論に至った議論の全過程を紹介します。

議論の過程

以降、筆者の問いかけを「Q」、AIの回答を「A」として、議論の流れを整理します。 AIの回答は要点を保持する形で整理していますが、主張の変遷が分かるよう、論旨はそのまま維持しています。

第1ラウンド:テスト容易性と依存性の逆転に差はあるか

記事の初期評価においてAIは、「テスト容易性や依存関係逆転の原則(DIP)の観点からの比較がない」ことを記事の弱点として指摘しました。 これに対して、筆者は次のように反証しました。

Q. テスト容易性や依存性の逆転については、いずれのアーキテクチャを採用したとしても、差はないものと考えています。 いずれの場合もこれを使用するエンジニアの節度の問題に帰結しており、アーキテクチャによる差にはならないと考えていますがいかがでしょうか。

A. ご指摘は半分同意で、半分は反論したいところです。

同意する点:到達できる上限は同じです。レイヤードでもリポジトリインターフェースをドメイン層に置いた時点でDIPは成立しており、モック差し替えによるテストも同等にできます。「クリーンだからテストしやすい」という言説の多くは、比較対象が「DDD以前の伝統的レイヤード(上から下へ具象依存する構成)」であることが多く、DDD前提のレイヤードと比較するなら、テスト容易性の理論的な差はほぼありません。

反論したい点:デフォルトと逸脱のしやすさには差があると考えます。レイヤードは、規約上、DIPを迂回する抜け道(アプリケーション層からインフラ層への直接呼び出し)が正規ルートとして存在します。節度あるエンジニアは使いませんが、節度は個人差・時間経過・メンバー交代で必ず劣化します。一方クリーンアーキテクチャは「内側は外側を知らない」を構造規則として課すため、逸脱がレビューで機械的に検出しやすい。

つまり、テスト容易性・DIPの「達成可能性」に差はなく(ご意見に同意)、「達成が構造的に強制されるか、個人の規律に委ねられるか」に差がある、という整理になります。

この時点でAIは「規律を構造で担保するか、人で担保するか」という差分を主張していました。 この主張は、後のラウンドで大きく崩れることになります。

第2ラウンド:構造による担保は、練度の切り捨てではないか

Q. クリーンは構造で担保した結果、全体としてはクラスが細切れになりすぎ、役割の集約が損なわれ、却って見通しを損ねているとも言えると感じています。 これは、習熟度の低いエンジニアに合わせた結果、全体としての練度を欠いているようにも見受けられますが、いかがでしょうか。

A. その見立ては本質を突いていると思います。クリーンアーキテクチャの構造規則は、判断を排除することで下限を保証する仕組みであり、下限の保証は必然的に上限の切り捨てを伴います。1ユースケース1クラス、境界ごとのDTO必須といった規則は「考えなくても壊れない」ためのものであって、「考えられる人がより良く作る」ためのものではない。習熟したチームにとっては、凝集を自ら設計できるのに規則がそれを禁じる、という逆転が起きます。

ただ、これを「練度を欠いている」と評価するかは、前提とする組織モデルに依存します。少数精鋭で長期在籍するチームなら構造規則は足枷ですが、人の出入りが激しい大規模組織では、「最も未熟なメンバーが書いたコードでも壊れない」ことの価値が、上級者の表現力の損失を上回る場面がある。つまりクリーンアーキテクチャは技術的な解というより、組織の平均と分散に対するリスクヘッジとして合理的な設計だと解釈できます。

第3ラウンド:低みに合わせることは、生産性を落とさないか

Q. 一般に熟練のエンジニアは、未熟なエンジニアの数倍から数十倍の生産性を発揮すると評される中、低みに合わせて高みを切り捨てるのは、却って生産性を落とす結果にはならないでしょうか。

A. 生産性の高いチームなら、その通りです。全員が高練度のチームにクリーンアーキテクチャの規則を課すのは、純粋な損失で、擁護の余地はありません。

ただ「低みに合わせると全体の生産性が落ちる」という一般化には、反論の余地があります。第一に、未熟なエンジニアの生産性は正ではなく負になり得ます。構造規則の価値は「未熟な人の産出を上げる」ことより「未熟な人が発生させる負債の分散を抑える」ことにあり、これは熟練者の時間を守る施策でもあります。第二に、規則が熟練者から奪うのは主に記述量であって、数十倍の生産性差の源泉(設計判断やデバッグの速さ)ではありません。削るものと守るものが非対称なので、混成チームでは期待値がプラスに出やすい。第三に、比較すべきは「規則あり混成チーム vs 規則なし混成チーム」であって、「規則あり混成 vs 全員熟練」ではありません。

「低みに合わせるべきか」はアーキテクチャの問いではなく、チーム構成という与件の問いです。

この時点までのAIの主張を要約すると、「未熟なエンジニアを含む混成チームでは、クリーンアーキテクチャの構造規則が品質の下限を担保する」というものでした。 次のラウンドで、この主張の核心が崩れます。

第4ラウンド(転回点):構造規則は、そもそも何を担保しているのか

Q. 少し違和感があります。 クリーンでは、ルールの曖昧さからくる実装時の設計余地を排除しているから、品質の下限を担保しやすいとのことでしたが、そもそも1ユースケース1クラスのように、適切な粒度でユースケースを分割できているならば、レイヤードでも問題なく実装できるように感じられます。 未熟なエンジニアやチームというのは、そもそもユースケースを適切な粒度に切り出すことができず、クリーンにおいても適切な実装を担保できるとは考えづらいです。

A. この指摘は正しく、私の前の議論の弱点を突いています。

クリーンアーキテクチャの構造規則が担保するのは「ユースケースが正しく切り出された後の配置と依存方向」であって、切り出しそのものではありません。そして設計で最も難しく、最も品質を左右するのは切り出しの方です。誤った粒度のユースケースは、クリーンの規則に完全準拠したまま存在できます。つまり構造規則は、上流の設計ミスを検出も防止もせず、むしろ**「規則に従っている」という体裁がミスを覆い隠すことすらある**。「下限の担保」という私の表現は、実際には担保範囲がかなり狭いことを認めるべきでした。

範囲を絞って言い直すと、クリーンが担保するのは「設計品質」ではなく**「配線品質」**(依存方向の逆流防止など、機械的に検査できる誤り)に限られます。

この帰結として、「練度の低いチームにはクリーン」という単純な条件分岐も修正が必要になります。ユースケースを切り出せないチームは、どちらのアーキテクチャでも設計品質は担保できない。本当の分岐は「ユースケース設計ができる人間がチームにいるか」であり、いないならアーキテクチャで解決しようとすること自体が誤り、という結論になります。

第5ラウンド:残った「配線品質」の差も、消えるのではないか

Q. 依存方向の制御については、現在ではArchUnitなどの防止層も存在するため、いずれの場合も大きな差にはなり得ません。 また、失敗の現れ方についても、ユースケースの分割に失敗している時点でその修復コストは決して小さく収まることはありえず、その差がそこまで大きくなるとは考えづらいです。 結局のところ、慎重な設計の担保こそドメイン駆動の本質であり、これを支えるために成熟したエンジニアの存在というものは、ほぼ不可欠なものと言えるのではないかと考えていますが、いかがでしょうか。

A. その結論には、留保なく同意できます。ここまでの議論で私が挙げた反論は、順に検証されて残余がほぼなくなりました。

  • 依存方向の担保 → ArchUnit等でアーキテクチャ非依存に実現可能。もはや構造規則の専売ではない
  • 失敗の修復コスト差 → 誤った切り出しの修復は、コードの再編成ではなく業務理解のやり直しが本体なので、物理配置は支配項にならない

残るものを突き詰めると、クリーンアーキテクチャが固有に提供するのは「判断の省略」だけであり、そしてDDDにおいて省略してよい判断はほとんど存在しない、ということになります。ドメイン駆動設計の中核は、ユビキタス言語の練成、境界づけられたコンテキストの発見、集約の切り出し——いずれもドメインとの対話を通じた継続的な判断そのものです。判断を構造で代替しようとする発想は、DDDの本質と根本的に相性が悪い。

つまり「成熟したエンジニアがいなくても回るDDD」という需要が先にあり、クリーンアーキテクチャの流行はその需要への供給だった——しかし供給されたのは配線規則であって設計能力ではないため、需要は実際には満たされていない

第6ラウンド:アーキテクチャで解決可能な規模には限度がある

AIは第5ラウンドの回答の中で、「成熟したエンジニアを確保できない組織の誠実な結論は、DDDを採用しないこと(Transaction ScriptやActiveRecordの方が正直な選択)」という補足をしました。これに対して筆者はさらに条件を精緻化しました。

Q. トランザクションスクリプトやアクティブレコードは、小〜中規模までのシステムであったり、小規模チームであれば一定の役割を果たすと理解しますが、一定規模を超えた途端、その品質の担保が急激に難しくなり、未熟なチームでも回せるアーキテクチャとはかけ離れたものとなります。 つまり、結局のところアーキテクチャで解決可能なシステム規模というものには限度があり、同様にアーキテクチャを扱えるエンジニアの習熟度というものにもアーキテクチャごとに一定の要件があるため、様々な規模の開発に対応したいと考えた時点で、成熟したエンジニアの存在は不可欠なものとなると考えましたが、いかがでしょうか。

A. その帰結は論理的に堅牢だと思います。

各アーキテクチャは「複雑性の許容上限」と「要求される習熟度の下限」という2つのパラメータを持っていて、この2つは独立ではなく連動しています。規模が上限に近づくにつれ、アーキテクチャが肩代わりしていた判断が人間側に戻ってくるので、実質的な習熟度要件は規模とともに上昇します。「未熟でも回る」は常に「この規模までなら」という隠れた条件付きであり、その条件を超えた瞬間に、どのアーキテクチャを選んでいても請求書は成熟したエンジニア宛てに届く。

そして「このシステムはどこまで育つか」という確信を下せるのがまさに成熟したエンジニアです。ここに再帰があります。アーキテクチャ選定という行為そのものが成熟を要求するため、「成熟を不要にするアーキテクチャ選び」は自己矛盾になる。

最終ラウンド:それでは、何を選べばよいのか

以上を踏まえて、筆者は本稿の主題である結論を提示しました。

Q. クリーンアーキテクチャの利用者の中には、レイヤードアーキテクチャと比較し、レイヤードアーキテクチャを古いものだからといった浅い理由で否定する者も少なくないように感じられます。 しかし、ここまでの議論を踏まえれば、新しい古いといった基準は役に立たないのは当然のものとして、結局成熟度的には同等のエンジニアが必要になることを考えると、そもそもクリーンアーキテクチャの抱えるデメリット(とくにユースケースの過剰な分離により、アプリケーション層におけるコンテキストが凝集しない)が、結果的には無視できないものとなり、却って古くから存在するレイヤードアーキテクチャのほうが採用メリットを感じられる選択となると考えていますが、いかがでしょうか。

A. 結論の方向には同意しますが、無条件の「レイヤード優位」ではなく、条件付きの優位として言い直したいです。

クリーンの売りだった「未熟でも回る」が、(1) 配線担保はArchUnit等でアーキテクチャ非依存に実現可能、(2) 設計品質はそもそも構造規則で担保不能、の二点で崩れた以上、両者の習熟度要件は同等になります。要件が同等なら、比較は純粋にコスト対効果の勝負になり、クリーンは「凝集の喪失」という恒常的なコストを払い続けるのに対して、対価として得ていたはずの担保はもう固有のものではない。この構図では、コンテキストの凝集を保てるレイヤードが優位になる——ここまでは論理的に堅い。

そのうえで、残余を挙げます。この結論が優位性を示すのは「レイヤード」というより「ハイブリッド」です。 純粋なレイヤードには、非ドメイン集合の永続化(ファイルI/O、メール、外部API)への一貫した答えを持たないという弱点が残ったままです。この一点についてはクリーンのPort概念が明確に優れており、レイヤードに選択的に移植する価値があります。「古いほうが良かった」という言い方は、逆方向の「新しいから良い」と同型の単純化に落ちる危険があります。

正確な結論は「レイヤード > クリーン」ではなく**「レイヤード + Portの選択的移植 > 純クリーン」です。「古いアーキテクチャの復権」ではなく、「新しいアーキテクチャから本当に新しかった部分だけを回収した」——「なぜクリーンアーキテクチャは生まれなければならなかったのか」という問いへの最終回答としては、その一点(非ドメイン永続化のPort化)を発明するためだった、と言えるのかもしれません。

まとめ:安易な安心への警鐘

議論の到達点を整理します。

  1. クリーンアーキテクチャの採用は、設計品質を何も担保しません。 担保されるのは配線品質のみであり、それすらArchUnit等で代替可能です。誤った粒度のユースケースは、規則に完全準拠したまま存在できます。「規則に従っている」という体裁は、むしろ設計ミスを覆い隠します。
  2. DDDを実践する以上、成熟したエンジニアの存在は、どのアーキテクチャを選んでも不可欠です。 ユビキタス言語の練成、コンテキストの発見、集約の切り出し——DDDの本体はすべて、構造では代替できない継続的な判断です。
  3. 習熟度要件が同等である以上、クリーンアーキテクチャの構造的コスト(1ユースケース1クラスによるコンテキスト凝集の喪失、境界ごとのDTO必須による記述量の増大)は、対価のないコストとなります。
  4. ただし、Port設計は回収する価値のある発明です。 ドメイン集合を操作するリポジトリはレイヤード流にドメイン層へ、非ドメイン集合の永続化はクリーン流にアプリケーション層のPortへ。この使い分けが、両者の良いとこ取りとなるハイブリッド構成です。

クリーンアーキテクチャを採用したという事実は、プロジェクトに何の保証も与えません。 「考えなくても壊れない」構造は、「考えるべきことを考えていない」ことに気づく機会も奪います。 アーキテクチャの形式に安心を求めるのではなく、ドメインを観察し、問いを立て、慎重に設計する—— その営みを支えられる体制づくりにこそ、投資すべきではないでしょうか。

余談:この議論自体について

本稿の議論はAIとの対話で行われましたが、AIの初期回答は「規律を構造で担保するか、人で担保するか」という、 クリーンアーキテクチャ擁護論としてよく見かける主張でした。 それが反証を重ねるごとに範囲を狭め、撤回され、最終的に真逆に近い結論へ到達しています。

この過程自体が、AI活用における一つの示唆になっていると感じます。 AIの初回回答をそのまま受け取ることは、クリーンアーキテクチャを採用して安心することと、構図として同じです。 価値があるのは回答(構造)ではなく、反証と修正の往復(判断)の方である—— 奇しくも、本稿の結論そのものでした。