Tsuzura

コードアーキテクチャの種類と選び方

コードアーキテクチャとは何かを初歩から説明し、MVC、レイヤード、Clean、Hexagonal、Vertical Sliceの違いと選び方を整理します。

コードアーキテクチャとは、プログラムをどのような部分に分け、その部分同士をどうつなぐかを決める方針です。コードが増えても、変更する場所と確認する範囲を判断できる状態をつくるために使います。

コードアーキテクチャを初めて学ぶ人が、変更内容に合う構成を選び、採用理由と見直し条件を説明できることを目指します。対象はコード内の構成で、サーバーの分け方や設計思想は扱いません。

利用者が達成したい結果と、完成と判断する条件がまだ決まっていない場合は、コードの構成を選ぶ前にそれらを整理します。

コードアーキテクチャとは

サービスの要件は「何を実現するか」を決めます。コードアーキテクチャは、その要件を実現するコードについて、次の3点を決めます。

  1. どの部分が何を担当するか
  2. どの部分からどの部分を利用してよいか
  3. 変更の影響をどの範囲に収めるか

一つの役割を担当するコードのまとまりを、この記事では「モジュール」と呼びます。モジュールが担当する役割が「責務」です。あるモジュールが別のモジュールの処理やデータを使わなければ動かない関係を「依存関係」と呼びます。

責務を分け、やり取りの方法を限定する区切りが「境界」です。コードアーキテクチャは、どこに境界を置き、境界を越えて何を利用できるかを決めます。

コード上では、フォルダやファイルの配置だけでなく、別のモジュールを参照する記述、境界を越えるデータの形、処理を呼び出す決まり、テストの範囲に表れます。フォルダ名をそろえるだけでは、依存関係の規則までは決まりません。

コードアーキテクチャが必要な理由

コードを変更すると、そのコードを利用している部分にも確認が必要になることがあります。責務と依存関係が曖昧なままコードが増えると、どこを直し、どこまで確認し、どのテストを実行すべきかを予測しにくくなります。ここでいうテストとは、処理が期待する結果になるかを確認するコードや手順です。

コードアーキテクチャによって責務と利用関係を明示すると、変更の中心になるモジュールと、影響を受ける可能性があるモジュールをたどりやすくなります。CMU/SEIのレイヤーに関する資料でも、レイヤーを単なる上下の配置ではなく、まとまりのある役割と「どのレイヤーがどのレイヤーを利用できるか」という関係で説明しています。

規則が共有されていれば、人が実装するときも、AIにコードの生成や変更を依頼するときも、同じ基準で置き場所と確認範囲を判断できます。ただし、特定の構成を採用しただけで、変更が簡単になると保証されるわけではありません。実際のコードが決めた依存関係を守っていることが必要です。

複雑な構成が正解ではない

境界を増やすと、境界を越えるための処理やデータ変換が増える場合があります。規則が多すぎると、簡単な変更にも多くのファイルを触ることになります。

目的は、有名な構成をすべて導入することではありません。現在の変更を説明できる最も単純な構成から始め、変更範囲を予測できなくなった場所にだけ新しい規則を加えます。

最初に知る基本構造:MVCとレイヤード

MVCとレイヤードは、どちらもコードを役割で分けます。ただし、分ける範囲が異なります。MVCは主に利用者との入出力を整理し、レイヤードはその奥を含むコード全体の利用順序を整理します。

MVCは入力・処理対象・表示を分ける

MVCは、Model、View、Controllerの3つに役割を分ける考え方です。ここでのModelは、生成AIのモデルではありません。

  • Modelは、アプリケーションが扱うデータの状態、対象分野の知識、業務上の処理を表します。
  • Viewは、利用者へ返す表示を担当します。
  • Controllerは、利用者からの入力を受け、必要な処理につなぎます。

1979年の原典では、Modelは対象分野の知識、ViewはModelの視覚表現、Controllerは利用者とシステムをつなぐ役割として説明されています。Models–Views–Controllers

現代のWeb向けMVCでは、Controllerが入力を受け、Modelやアプリケーションの処理と連携し、返すViewを選ぶ形が一般的です。ASP.NET Core MVCの公式概要も、この役割分担を説明しています。

利用者からの入力
        ↓
   Controller
      ├──→ Modelやアプリケーションの処理
      └──→ View ──→ 利用者への表示

矢印:実行時に処理が進む向き

画面を返さず、ほかのプログラムへデータを返す場合は、Viewを使わない構成もあります。

MVCが決めるのは、主に利用者との入出力に近い部分です。データの保存、業務上の判断、外部サービスとの通信まで、アプリケーション全体の依存関係を決めるものではありません。

レイヤードは役割で分け、利用順序を決める

レイヤードアーキテクチャは、コードを技術的な役割ごとの層に分け、上の層から下の層へ利用する順序を決めます。Webアプリケーションでは、次の3層がよく使われます。

層 担当すること
入出力の層 画面や通信から入力を受け、結果を返す
処理の層 アプリケーションの手順や業務上の判断を実行する
データアクセスの層 データベースなどの保存先を読み書きする

データベースは、アプリケーションが使うデータを保存し、検索するための仕組みです。

入出力の層
      ↓
処理の層
      ↓
データアクセスの層

矢印:利用を許す向き

レイヤードには、一つ下の層だけを利用できる構成と、すべての下位層を利用できる構成があります。重要なのは、採用した利用順序を明示することです。上位と下位が無制限に利用し合うと、層を分けた目的が崩れます。Software Architecture Documentation in Practice

小さく単純な処理では、レイヤードは役割と処理の流れを見つけやすい構成です。一方で、重要な業務ルールがデータベース用のコードを直接利用すると、保存方法の変更が業務ルールへ広がることがあります。MicrosoftのWebアプリケーション構成ガイド

MVCとレイヤードの違い

MVCは利用者との入出力に近い部分の役割を分けます。レイヤードは、その奥を含むコードを技術的な役割で分け、利用してよい順序を定めます。

観点 MVC レイヤード
主に分ける範囲 利用者との入出力に近い部分 入出力、処理、データ保存を含むコード
主に決めること Model、View、Controllerの役割 技術的な役割と、層を利用する順序
併用 入出力の層にMVCを置ける 入出力の層でMVCを使える

MVCを使っているから、アプリケーション全体の構成も決まっているとは限りません。MVCで入口を整理し、その奥をレイヤードで分ける構成は両立します。

業務ルールと外部技術を分ける:CleanとHexagonal

Clean ArchitectureとHexagonal Architectureは、業務ルールを外部技術の詳細から分けたいときに使います。目的は近いものの、決める範囲が異なります。

「業務ルール」は、そのサービスで何を受け入れ、どう判断し、どう処理するかを定める規則です。「外部技術」は、画面や通信を扱う仕組み、データベース、ほかのサービスとの接続手段などを指します。

Clean Architectureは依存関係を内側へ向ける

Clean Architectureの中心は、業務ルールを中心に置き、コード上の依存関係を外側から内側へ向ける「依存規則」です。

画面・通信・データベースに接続するコード
                    ↓
          アプリケーションの処理
                    ↓
                業務ルール

矢印:コード上で利用を許す向き

ここでいうコード上の依存関係は、あるモジュールが別のモジュールの処理やデータを参照する関係です。内側の業務ルールは、外側で使う製品名やデータ形式を知らない状態にします。The Clean Architecture

内側から保存や通知を依頼する必要がある場合は、内側に「どの処理を、どの入力と出力で呼ぶか」という決まりを置き、外側のコードがその決まりを実装します。この決まりを、この記事ではインターフェースと呼びます。画面を指す言葉ではありません。

Clean Architectureの図でよく示される円は、固定のフォルダ数ではありません。業務ルールを外部技術から分ける必要が小さい段階で境界を増やすと、インターフェースや変換処理の負担が大きくなります。

Hexagonal Architectureは外部との接続方法を分ける

Hexagonal Architectureの正式なパターン名はPorts and Adaptersです。アプリケーションの内側と外部を分け、その接続方法をPortとAdapterで定めます。

Portは、内側と外部がやり取りする処理、入力、出力の決まりです。この決まりを「契約」と呼びます。Portは設計上の契約で、コードではインターフェースとして表す場合があります。Adapterは、外部の形式をPortの契約に合わせて変換するコードです。

入力側では、画面や通信からの入力をAdapterがPortへ渡します。出力側では、データ保存や通知の契約を外部向けのAdapterが実装します。The Hexagonal (Ports & Adapters) Architecture

Portの契約をアプリケーションの言葉で定め、外部固有のデータ形式をAdapterで変換すれば、外部技術の詳細を内側へ持ち込まずに済みます。その一方で、PortとAdapterを増やすほど、インターフェースと変換処理も増えます。交換する可能性がある、外部なしでテストしたい、外部サービスの障害に対応する処理を境界へまとめたい、といった理由がある場所に絞って使います。PortとAdapter自体が障害を防ぐわけではありません。

CleanとHexagonalの違い

Cleanは業務ルールへ向かう依存関係と内側の段階を決め、Hexagonalはアプリケーションの内側と外部をつなぐ方法を決めます。目的は近いものの、規定する範囲が異なります。

観点 Clean Architecture Hexagonal Architecture
主に決めること 業務ルールへ向かう依存関係と、内側の段階 アプリケーションの内側と外部をつなぐPortとAdapter
注目する範囲 業務ルール、アプリケーションの処理、外部の詳細 アプリケーションの内側と外部
一緒に使えるか Hexagonalの内側をCleanの段階で分けられる 外部との境界にPortとAdapterを使える

両者は同義語ではありませんが、対立するものでもありません。Hexagonalの内側をCleanの考え方で分ける構成も可能です。Hexagonal Architecture Explained, Updated 1st Edition

機能単位でまとめる:Vertical Slice

Vertical Slice Architectureは、コードを技術的な役割ではなく、機能やユースケースごとにまとめる考え方です。ユースケースとは、利用者や外部のシステムが、アプリケーションで達成したい一つの結果です。

レイヤードでは、入力、処理、データ保存のコードを役割ごとにまとめます。Vertical Sliceでは、一つの結果に必要な入力、確認、処理、保存、テストを一つの「スライス」としてまとめます。提唱者のJimmy Bogardは、個別のリクエストを中心にコードをまとめ、変更の軸に沿って結合する構成と説明しています。Vertical Slice Architecture

スライス内の分け方は固定されません。処理が単純な間は小さく保ち、複雑になった部分だけを分けられます。関連するコードとテストが実際に同じスライスへまとまっていれば、そのスライスを探索の起点にできます。

一方で、利用者の確認、共通の業務ルール、データ全体の構造、記録処理などは複数のスライスに影響します。共通部分まで各スライスへ重複させると、一つの規則を変えるために多くのスライスを直すことになります。Vertical Sliceを使っても、共有する責務と依存関係は別に決める必要があります。

コードアーキテクチャの種類は組み合わせられる

MVC、レイヤード、Clean、Hexagonal、Vertical Sliceは、決める対象が異なるため併用できます。同じ基準で分けた排他的な選択肢ではありません。

考え方 決める対象 検討する状況
MVC 利用者との入出力に近い役割 画面や通信の入口を整理する
レイヤード 技術的な役割と利用順序 単純な処理を役割ごとに分ける
Clean Architecture 業務ルールへ向かう依存関係 業務ルールを外部技術から分ける
Hexagonal Architecture アプリケーションと外部の接続方法 交換や分離が必要な外部との境界をつくる
Vertical Slice Architecture 機能変更をまとめる単位 機能単位の変更が複数の技術的な層をまたぐ

入力部分にMVCを使い、コード全体にはレイヤードの利用順序を設けられます。機能をVertical Sliceでまとめ、その内部にはCleanの依存規則を使えます。外部との接続には、HexagonalのPortとAdapterを組み合わせられます。

使う考え方を増やすほど、守る規則と変換処理も増えます。組み合わせること自体を目的にせず、どの変更をどこへ収めたいかを説明できるものだけを採用します。

コードアーキテクチャの選び方

コードアーキテクチャは、予定する変更の影響範囲から選びます。修正範囲を予測できない場所だけに、新しい境界や依存規則を加えます。

最初は単純な構成から始める

現在ある問題に必要なものだけを選びます。次の表は原典による順位ではなく、ここまで説明した定義から本記事で整理した判断基準です。

現在の状況 最初に検討する構成
データの登録、表示、更新が中心で、業務ルールが少ない MVCと単純なレイヤード
業務ルールが、画面やデータベース用のコードを直接利用している Cleanの依存規則
外部サービスや保存方法を交換したい、または外部なしで処理をテストしたい 必要な境界だけにHexagonalのPortとAdapter
機能追加のたびに、入力、処理、保存、テストの各フォルダを行き来する Vertical Slice
一つの共通ルールの変更が、多くの機能へ広がる 共通の責務を置くモジュールと、その依存規則を見直す

処理が単純で、変更範囲を予測できているなら、MVCと単純なレイヤードで十分な場合があります。Clean、Hexagonal、Vertical Sliceは、名前が高度だから追加するものではありません。

予定する変更から影響範囲を確認する

構成名ではなく、実際に予定する変更を使って判断します。「変更が広がる」とは、一つの変更理由によって、本来は別の責務まで修正しなければならない状態です。

  1. 近く予定している変更をいくつか書く
  2. 各変更で修正するモジュール、確認する依存関係、実行するテストを挙げる
  3. 修正範囲を予測できない場所だけに、新しい境界や依存規則を加える
  4. 新しい構成を前提に、同じ変更の修正範囲をもう一度確認する

既存のコード全体を一度に並べ替える必要はありません。新しく変更する部分から規則を適用し、変更前と同じ結果になることをテストで確認します。

採用した構成、採用した理由、採用しなかった構成、見直す条件は短く記録します。判断記録の詳しい書き方は別の記事で扱います。

AIを使うならVertical Sliceがよいのか

ここでいうAIは、コードを生成・変更する開発支援AIを指します。Vertical Sliceがほかの構成よりAIの精度や速度を高めると直接示した比較研究は、2026年8月19日時点の一次資料調査では確認できませんでした。そのため、「AIならVertical Sliceが正解」とは言えません。

ただし、一つの機能の入口、処理、保存、関連テストが同じスライスから見つかる構成なら、AIへ変更範囲を伝えやすくなる可能性があります。GitHub Copilotのベストプラクティスも、複雑な作業を小さな作業へ分け、要件と関連ファイルを具体的に渡すよう案内しています。

AIにとって重要なのは、Vertical Sliceという名前よりも、次の状態です。

  • 機能の入口と関連するコードを見つけられる
  • 利用してよい依存関係が文書化されている
  • 利用を許していないモジュール参照を、ツールやテストで自動検出できる
  • 一つの依頼で達成する結果と、実行するテストが明確になっている
  • 複数の機能へ広がる変更が明記されている

OpenAIが公開した一つの開発事例では、業務領域ごとに固定したレイヤーと依存方向を設け、利用を許していない参照を自動検査と構造のテストで確認しています。公開記事からはVertical Sliceを併用しているか分からず、この一例だけで特定の構成を一般的な正解にはできません。Harness engineering: leveraging Codex in an agent-first world

AIが生成したコードが動いても、既存の責務や依存規則に合うとは限りません。要求どおりか、既存の構成を守っているか、必要なテストを通るかは人が確認します。GitHub公式のAI生成コードのレビューチュートリアルも、人による確認手順を案内しています。

選択できたと判断する基準

次の4点を説明できれば、構成を選ぶための最低限の判断ができています。

  • 各モジュールの責務を一文で説明できる
  • どのモジュールからどのモジュールを利用してよいか説明できる
  • 予定する変更の主な修正箇所と、変えない箇所を予測できる
  • 変更後に実行するテストを特定できる

説明できない場合は、規則が不足しているか、反対に複雑すぎる可能性があります。コードアーキテクチャに唯一の正解はありません。現在の変更を説明でき、必要になったときに見直せる構成を選びます。

ブラウザ、サーバー、ビルド時のどこで処理するかは、コード内部の責務と依存をどう分けるかとは別の判断です。SSR・CSR・SSG・ISRの選び方で、実行場所とデータ・キャッシュの境界を確認します。

出典

  1. CMU/SEIのレイヤーに関する資料resources.sei.cmu.edu
  2. Models–Views–Controllerszenodo.org
  3. ASP.NET Core MVCの公式概要learn.microsoft.com
  4. MicrosoftのWebアプリケーション構成ガイドlearn.microsoft.com
  5. The Clean Architectureblog.cleancoder.com
  6. The Hexagonal (Ports & Adapters) Architecturealistair.cockburn.us
  7. Hexagonal Architecture Explained, Updated 1st Editionalistaircockburn.com
  8. Vertical Slice Architecturejimmybogard.com
  9. GitHub Copilotのベストプラクティスdocs.github.com
  10. Harness engineering: leveraging Codex in an agent-first worldopenai.com
  11. GitHub公式のAI生成コードのレビューチュートリアルdocs.github.com