システム開発では、機能追加や仕様変更が繰り返し行われます。
そのため、設計を十分に考えずに実装を進めてしまうと、コード同士が複雑に依存し合い、「一部を修正しただけで別の機能まで壊れてしまう」「テストが難しい」「新しい技術へ移行できない」といった問題が発生しやすくなります。
このような課題を解決する設計思想として広く知られているのが、「クリーンアーキテクチャ(Clean Architecture)」 です。
データベースやWebフレームワークなどの技術要素から業務ロジックを切り離し、システムの中心となるビジネスルールを長く保守できるよう設計することを目的としています。
現在ではWebアプリケーションだけでなく、モバイルアプリやAPIサーバー、クラウドシステムなど幅広い開発現場で採用されており、長期間運用されるシステムほどその効果を発揮します。
この記事では、クリーンアーキテクチャの基本的な考え方から、各レイヤーの役割、メリット・デメリット、実装方法、運用時の注意点まで詳しく解説します。
クリーンアーキテクチャとは
システム設計におけるクリーンアーキテクチャの概要
クリーンアーキテクチャとは、ソフトウェアの保守性・拡張性・テスト容易性を高めるために考案されたアーキテクチャ設計手法です。
この考え方はソフトウェアエンジニアの Robert C. Martin(通称 Uncle Bob)氏が提唱したもので、「ソフトウェアの中心にはビジネスルールを置き、技術的な要素はその外側に配置する」 という設計思想に基づいています。
アプリケーション開発において、画面・データベース・フレームワークなどの実装に業務ロジックが密接に結び付いてしまうケースは少なくありません。
その結果、データベースを変更したいだけのケースで業務ロジックまで修正する必要が生じたり、フレームワークをアップデートしただけで大量のコード修正が発生したりすることがあります。
クリーンアーキテクチャでは、業務ロジックをアプリケーションの中心に配置し、それ以外の技術要素を外側へ配置します。
依存関係の方向を 「常に外側から中心へ」 向かわせ、コアとなる機能をフレームワークやDBなどに依存しない状態にすることで、技術が変わっても業務ロジックへの影響を最小限に抑えられるようになります。
「データベースを交換してもビジネスロジックは変わらない」 「Webフレームワークを乗り換えても業務処理はそのまま利用できる」 といったように、アプリケーションの根幹となる処理への影響を無くすことによって、仕様変更や機能追加に強く保守性に優れた状態を保つための設計が、クリーンアーキテクチャなのです。
同心円の図と4つの層の役割
クリーンアーキテクチャは、以下のような同心円状のレイヤー構造で表現されることが一般的です。
![]()
円の最も内側に位置するのが、Enterprise Business Rules 層 (Entity) です。この層には、企業やサービスの本質となる業務ルールを配置します。
例えばECサイトの場合、「商品」「注文」「顧客」といった概念や、「在庫が0の場合は購入できない」 「商品価格はマイナスになってはならない」 といったような、システムに依らない不変のルールがここに該当します。
Entityはその他の技術的要素に依存せず、純粋な業務知識だけを持つように設計します。
その外側にあるのが、Application Business Rules 層 (Use Case) です。
この層では、「商品を購入する」 「ユーザー登録を行う」 「予約をキャンセルする」 といったサービス提供に必要な行為を実現するにあたって、具体的にどのような処理を行うかといったアプリケーション固有のルールを定義します。
Entityを利用して業務フローを組み立てますが、データベースや画面の実装方法などには依存しないように設計します。
さらに外側には、Interface Adapters 層があります。
この層は言わば、外部との橋渡しを担当する層であり、HTTPリクエストやJSON、SQLなどをUseCaseが扱いやすい形へ変換する役割を担っています。
ControllerやPresenter、Repositoryなどがこの層に配置されます。
最も外側に位置するのが、Frameworks & Drivers 層です。
ここにはWebフレームワーク、データベース、UI、外部API、ファイルシステムなどといった技術的要素を配置します。
Entityや Use Caseとの直接的な関係を切り離すことにより、将来的な技術変更などにも対応しやすくなっています。
外側から内側へ向かう「依存性のルール」の仕組み
![]()
クリーンアーキテクチャで最も重要なのが、依存性のルール(Dependency Rule)です。
このルールでは、「依存関係は必ず外側から内側へ向かう」と定義されています。
そのため、
Framework
↓
Interface Adapter
↓
Use Case
↓
Entity
という方向に依存することはできますが、その逆はできません。
例えば、Entityがデータベースライブラリを直接利用してしまうと、データベースを変更した際にEntityまで修正しなければならなくなります。
これはクリーンアーキテクチャの目的に反します。
そのため、実際の開発ではメソッドの定義と具体的な処理内容の実装を別に分け、外側の層で処理内容を実装、内側の層で定義したメソッドを利用することにより、依存関係を外から内へと逆転させます。
これにより、内側の層は外側の具体的な構造を知る必要なく処理を呼び出すことができます。
結果として、フレームワークやDBを別のものへと移行したり、途中で仕様が変更されたりしても、業務ロジックに影響を与えずに済むようになります。
クリーンアーキテクチャを採用するメリット・デメリット
クリーンアーキテクチャを導入するメリット
| 観点 | メリット | デメリット・注意点 |
|---|---|---|
| 保守性 | 修正範囲を限定できる | レイヤー間の責務が曖昧になりやすい |
| テスト | UseCase単体で高速テスト可能 | – |
| 技術変更 | 外側レイヤーのみ修正で対応可 | – |
| 開発スピード | 長期運用で恩恵大 | 初期の実装速度が落ちる/過剰設計になりやすい |
| 学習コスト | – | 設計思想の理解に時間がかかる |
最大のメリットは、機能変更に強いシステムを構築できることです。
システム開発では、仕様変更や新機能追加は避けて通れません。
クリーンアーキテクチャでは役割ごとにコードが整理されており、互いのコードへの影響も少ないため、修正範囲を限定して進めることができます。
また、ビジネスロジックがフレームワークから独立しているため、単体テストを書きやすくなることも大きな利点です。
UseCaseだけをテストできるため、データベースやWebサーバーを起動せずに高速なテストを実施できます。
さらに、技術変更にも柔軟に対応可能です。
WebフレームワークやORM、データベースを入れ替える場合でも、外側のレイヤーのみを修正すれば済むケースが多く、長期間運用するシステムほど恩恵を受けやすくなります。
クリーンアーキテクチャを利用する際のデメリットと注意点
一方で、クリーンアーキテクチャにはデメリットもあります。
最も大きいのは、アプリケーション全体の構造が複雑になりやすい点です。
小規模なWebアプリでも、Entity、UseCase、Repository、Controllerなど、複数のクラスを作成する必要があり、「少し処理を書くだけなのにファイル数が多い」と感じることがあります。
また、設計思想を理解していないと、レイヤー間の責務が曖昧になり、「UseCaseにSQLを書いてしまう」 「EntityがHTTP通信を行う」 といったパターンが生まれやすくなります。
構造をしっかりと理解した上でコードベースに落とし込む必要があるため、学習コストも少々高めとなります。
加えて、開発初期は実装スピードが落ちるケースもあります。
レイヤー設計やインターフェース作成に時間がかかるため、短期間で完成させる小規模システムでは過剰設計になる場合もあります。
そのため、クリーンアーキテクチャは「必ず採用すべき設計」ではなく、システム規模や運用期間、チーム人数などを考慮して導入することが重要です。
クリーンアーキテクチャの実装とフォルダ構成
クリーンアーキテクチャに基づいたフォルダ構成
実際のプロジェクトでは、レイヤーごとにディレクトリを分割する構成が一般的です。
![]()
以下はその一例です。
src/
├── domain/
│ ├── entities/
│ ├── repositories/
│ └── valueObjects/
│
├── application/
│ ├── usecases/
│ └── dto/
│
├── infrastructure/
│ ├── database/
│ ├── repository/
│ └── external/
│
├── presentation/
│ ├── controllers/
│ ├── presenters/
│ └── routes/
│
└── main/
└── dependencyInjection/上記の例では、まずEntityやValueObjectなど、業務ルールを表すコードをDomain層へ配置しています。
次に、ユースケースをApplication層へ実装し、業務フローを組み立てます。
この層では定義したインターフェースのみを利用し、実際のデータ取得方法は記述しません。
Infrastructure層では、データベースアクセスやRepository実装、外部APIとの通信などを担当します。
最後に、Presentation層でHTTPリクエストや画面表示を処理し、アプリケーション層の呼び出しを行います。
このように、役割を明確に分けることで各層が独立し、保守性の高い構成になります。
実装時に迷いやすいポイントと対策
初心者が最も迷いやすいのは、「どの処理をどの層へ置けばいいのか」という点です。
主な判断基準としては、以下のように振り分けられます。
| 層 | 配置する処理 | 判断基準 |
|---|---|---|
| Entity | システムに依らない業務ルール | 人間の手作業でも成立するか |
| UseCase | アプリケーション固有の処理 | このサービス特有のフローか |
| Infrastructure | 外部連携・インターフェース実装 | DB・外部APIとのやり取りか |
| Presentation | HTTP API・画面表示 | UIやリクエスト/レスポンス処理か |
最も重要なのは、クリーンアーキテクチャの根幹となる Entityの設計です。
画面表示用のフォーマットやデータベースアクセスまで記述したりと、Entityへ何でも実装してしまうと本来の役割から外れてしまうため、依存関係をしっかりと切り離して設計することが重要となります。
一方で、UseCaseへ大量のビジネスルールを書き込みすぎるケースもあります。
複数のユースケースで共通利用する業務ルールは、Entityやドメインサービスへ切り出した方が再利用しやすくなる場合があるため、実装する前に業務内容やアプリケーションの要件などをしっかりと整理してから開発を進めるといいでしょう。
クリーンアーキテクチャを上手に運用するための注意点
システム規模に応じた設計の進め方
小規模なツールや短期間で終了するプロジェクトでは、最初から完全なクリーンアーキテクチャを導入すると過剰設計になる場合があります。
まずはEntityとUseCaseだけを分離し、システムの成長に合わせてRepositoryやPresenterなどを追加する段階的な導入も有効です。
一方で、大規模システムや長期間運用するサービスでは、初期段階から役割を明確に分離しておくことで、将来的な保守コストを大きく削減できます。
フレームワークやデータベースとの距離を保つコツ
クリーンアーキテクチャでは、「フレームワークは道具」という考え方を徹底することが重要です。
例えば、ORMのエンティティをそのまま業務モデルとして利用したり、Entityの中でHTTPリクエストを送信したりすると、技術要素への依存が強くなってしまいます。
インターフェースを介して依存関係を管理し、業務ロジックをできるだけ純粋なコードとして保つことで、将来的な技術変更にも柔軟に対応できるシステムになります。
まとめ
クリーンアーキテクチャは、業務ロジックをシステムの中心に据え、フレームワークやデータベースなどの技術要素から切り離して設計するアーキテクチャです。
同心円構造と依存性のルールによって役割を明確に分離することで、保守性や拡張性、テスト容易性を高められます。
一方で、設計や実装の複雑さが増す要因となるため、小規模なプロジェクトでは過剰設計にならないよう注意も必要です。
システムの規模や運用期間に応じて適切に採用することで、長期的に保守しやすく変更に強いソフトウェアを実現できます。