はじめに
エンジニアとして開発に携わっていると、「クリーンアーキテクチャ(Clean Architecture)」という言葉を耳にする機会が多いと思います。
しかし、いざ調べてみると難しい専門用語ばかりで、「結局どういうことなの?」と挫折してしまった方もいるのではないでしょうか。
僕自身、最初は概念図を見てもなかなか理解できず、「結局どういうことなんだろう?」とモヤモヤしていました。今でも学びの途中ですが、この記事は自分自身の理解を整理するアウトプットとして、そしてこれから学び始める方の助けになればと思い執筆します!
この記事を読むメリット
- クリーンアーキテクチャの「目的」がわかる
- 4つの層(レイヤー)の役割を直感的に理解できる
- 「依存性のルール」という一番重要な概念が図解でわかる
- 実際の処理がどの層を通って行われるのかイメージできるようになる
前提条件
- 「データベース」や「UI(ユーザーインターフェース)」といった基本的なIT用語をなんとなく知っていること
- 特定のプログラミング言語の知識は不要です!概念的なお話になります
本編
1. クリーンアーキテクチャとは?
一言で言うと、「システムの部品を取り替えやすく、テストしやすくするための設計のルール」です。
例えば、家を建てる時に「壁紙を変えたいだけなのに、家の柱まで壊さないといけない」構造になっていたら大変ですよね。
ソフトウェアも同じで、「画面のデザインを変えたいだけなのに、裏側の複雑な計算システムまで壊れてしまった」という事態を防ぐために、クリーンアーキテクチャという設計手法が使われます。
クリーンアーキテクチャの最大の目的
ビジネスの中心となる重要なルール(核)を、データベースやWebフレームワークといった「外部の技術」から守り、独立させることです。
2. 4つの層(レイヤー)の役割
クリーンアーキテクチャでは、システムを大きく4つの層(レイヤー)に分けて考えます。外側から順番に見ていきます。
| レイヤー名 | 役割 | 具体例 |
|---|---|---|
| 1. Frameworks & Drivers |
一番外側:データの入り口と出口 画面から値を送ったり、実際にデータを保存する「道具」たちの層です。 |
・画面から入力された値の受け取り ・データベースへの実際の登録処理 |
| 2. Interface Adapters |
中間:外側の道具と内側の処理の「橋渡し役」 外側の道具(1)と、内側のルール(3, 4)の間でデータを翻訳して受け渡します。 |
・画面からの値を使いやすい形に変換(コントローラー) ・データベースとの仲介 |
| 3. Use Cases |
内側:アプリ固有の「手順・やること」 システムが「どんな風に動くか」という一連の流れを担当します。 |
・「ユーザーを新しく登録する」手順 ・「商品を買い物かごに入れる」手順 |
| 4. Entities |
中心:絶対に変わらない「基本ルール」 アプリの仕組みがどう変わっても、絶対に守らなければいけないデータそのもののルールです。 |
・「ユーザー」や「商品」というデータ構造 ・例:「年齢は0以上でなければならない」 ・例:「注文の合計金額がマイナスになってはいけない」 |
3. 一番大事な「依存性のルール」
クリーンアーキテクチャを理解する上で、絶対に覚えておきたいのが「依存性のルール」 です。
これは、「外側の層は内側の層を知っていても良いが、内側の層は外側の層を知っていてはいけない」というルールです。つまり、矢印(依存関係)は常に外側から内側へ向かいます。
4. 依存関係の構造
文字だけだとイメージしづらいので、この「依存性のルール」をMermaid図で表現してみました。
💡ポイント1
矢印はすべて「外側 → 内側」に向かっています。
つまり、データベースやUIなどの技術的な部分は、中心のビジネスルールを知っていますが、中心側は外側を知りません。
例えば、データベースを MySQL から PostgreSQL に変更しても、Entities や Use Cases は影響を受けにくい構造になります。
💡ポイント2:「依存の向き」≠「処理が進む向き」
クリーンアーキテクチャを学び始めた人が一番勘違いしやすいのが、 「矢印(依存)が外から内なら、処理も外から内にしか進まないの?」 という点です。
結論から言うと、「処理の流れる順番」は内から外へ向かうこと もあります。
- 依存の向き(相手を知っている状態): 常に「外 → 内」(絶対に変わらない)
- 処理の向き(プログラムが動く順番): 「内 → 外」に行くこともある(例:手順の途中で、外側にあるDBにデータを保存しに行くなど)
「処理は外へ出ていくのに、依存の矢印は内に向いたままにする」という、この一見矛盾するようなねじれ現象をきれいに解決するために、このあと解説する 「インターフェース(窓口)」 というものが登場します。
5. 実際の処理の流れ(シーケンス図)
では、実際にユーザーが「購入ボタン」を押した時、この4つの層がどうやって連携するのか?
レストランの例えを交えながら、動き(シーケンス)を図解してみます。
このように、「外側(メニューやウェイター)が変わっても、内側(調理手順やレシピ)はそのまま使える」という状態を作ることが、クリーンアーキテクチャのメリットです。
6. 依存性逆転の原則
きれいに流れているように見える処理ですが、
実際のシステム開発では、この流れの途中で 『データベースにデータを保存する』 という処理がよく出てきます。
「データをデータベースに保存する」という命令を出すのは 3. Use Cases(内側:手順) ですが、実際にデータを保存する土台(MySQLなど)は 1. Frameworks(一番外側:道具) にあります。
普通に考えると、内側から外側に向かって「データを保存して!」と命令の矢印が向くはずですよね。
これでは、大原則である「矢印は外から内へ」という依存性のルールを破ってしまいます。
内側の手順が、外側のデータベースの存在を知ってしまっているからです。
そこで、解決策 「インターフェース(窓口)」 というものが出てきます。
これが、クリーンアーキテクチャの特徴の一つである 「依存性逆転の原則(DIP: Dependency Inversion Principle)」 です。
内側の世界に、 「保存したいデータをこの窓口に置いておくから、あとは誰か(外側の世界の人)がうまいこと保存しておいてね!」 という【窓口(インターフェース)】だけをポツンと用意しておきます。
そして、外側のデータベースを「その窓口に合わせて、私が保存処理を引き受けます!」と、内側に歩み寄る形にします。
図にすると、こうなります。
図を見るとわかる通り、外側の世界(データベース)から、内側の世界(窓口)に向かって矢印が突き刺さっていますよね。
処理の流れ: 「手順(内)」から「データベース(外)」へ進む
矢印の向き: 「データベース(外)」から「窓口(内)」へ向かう
処理は内から外へ流れるのに、矢印(知っている状態)だけがグルンと逆転します。
専門用語では、このように窓口(インターフェース)を使って依存関係を逆転させることを 「依存性逆転の原則(DIP: Dependency Inversion Principle)」 、そして実際にその窓口へ外側のデータベースの部品をガチャンと結合することを 「依存性注入(DI: Dependency Injection)」 と呼びます。
💡ポイント: 「2 → 1」の矢印があっても問題ない
この図では Repository実装 → DB のように、外側(2 → 1)へ向かう矢印があります。
「あれ?『矢印は外から内へ』じゃないの?」と思うかもしれませんが、
クリーンアーキテクチャで厳密に守るのは、「ビジネスロジックへの依存関係の向き」 です。
重要なのは、
Repository実装 → UseCases層のInterface
という 「外側が内側のビジネスロジックに依存する」 向きです。
一方で、Repository実装 → DB は「DBという道具を利用している」関係なので、2 → 1 の矢印が存在しても問題ないことが多いです。
まとめ
今回は、IT初心者向けにクリーンアーキテクチャの基本的な概念を図を使って解説しました。
- 目的: システムを部品化し、変更に強く・テストしやすくすること
- 構造: システムを4つの層に分け、それぞれに役割を持たせる
- 依存性のルール: 依存関係(矢印)は常に「外側から内側へ」向かうため、中心のルールは外の変更に影響されない
コードに落とし込むとまた難しくなりますが、まずはこの「外から内への一方通行」と「役割分担」のイメージを頭に入れておくと設計しやすいと思います!
今後pythonを用いたクリーンアーキテクチャ実装例も執筆する予定です!✒️
最後までお読みいただきありがとうございました!✨