フクロウと学ぶアーキテクチャ #1 ─ レイヤードアーキテクチャ入門
※本記事は個人の知見と学習の記録であり、所属組織の見解を代表するものではありません。
🦉フクロウと学ぶアーキテクチャ #1
レイヤードアーキテクチャ ─ いちばん素朴で、いちばん残っている基本形
ソフトウェアアーキテクチャの旅。その最初のステップは レイヤードアーキテクチャ(Layered / N-Tier) です。
本記事では概念を学びつつ、あわせて GitHub に用意した最小構成サンプル を使って体験できるようにしています。
👉 サンプルコード(Python / 最小レイヤード構成)
歴史が長く、いまでも多くのフレームワークが採用する「基本の地図」。
AI エージェント時代の複雑な設計に進む前に、この“素朴な型”を体で理解しておくと迷子になりにくくなります。
🏛️ レイヤードアーキテクチャとは?
レイヤードとは、その名の通り 責務ごとに層(Layer)を積み重ねる構造 です。
代表的には次の4層で表現されます。
- Presentation Layer(UI / Controller)
- Application Layer(ユースケース・アプリの振る舞い)
※実装では「サービス層が肥大化する」ケースが多いですが、本記事では ユースケースに特化した“薄いアプリケーション層” という整理で統一します。
- Domain Layer(ビジネスロジック・エンティティ)
- Infrastructure Layer(Repository / DB / 外部API)
依存方向は 「上 → 下」の一方向。
逆方向に依存しないことで、コードが整理され、迷子になりにくくなります。
フレームワークによっては “3層(Controller / Service / Repository)” と簡略化されることもありますが、依存方向の考え方は同じです。

📐 依存方向のルール
レイヤードで最重要なのは、依存が 上 → 下 の一方向 に限定されることです。
- UI → Application → Domain → Infrastructure
- 逆方向は禁止(インフラがUIを知る…など)
依存方向が守られるだけで、設計が崩れにくくなります。
🚫 やりがちアンチパターン
よくある “ショートカット依存” の例:
- Controller → Repository へ直接アクセス
- Domain → DB へ直接アクセス
- Application があらゆる層に手を伸ばす
このあたりがプロジェクトを“スパゲッティ化”させる温床になります。
🧩 MVCモデルとの違いは?
「レイヤードとMVCって何が違うの?」という疑問をよく聞きます。
結論から言うと “目的が違うため、併用もできる” 別の概念 です。
-
MVC(Model / View / Controller)
UI や Presentation 層の中での 役割分担モデル。
どこが表示を担当し、どこが入力処理を担当するかを分ける考え方です。 -
Layered Architecture(レイヤード)
アプリケーション全体の 依存方向と責務の区切り方。
UI、ユースケース、ドメイン、インフラを「層」で分けます。
つまり、MVC は Presentation Layer の中に入れられる “UI の構造”、
レイヤードはアプリ全体の “大きな地図” を示す構造です。
Rails や Django など多くのフレームワークでは
「MVC(風)構造 × レイヤード的な依存方向」
が混ざっているため、両者がよく混同されます。
本記事では MVC は UI 内部の話にとどめ、アプリ全体の構造(レイヤード) にフォーカスしています。
🧪 Pythonで体験するレイヤード
この章では 概念がわかりやすい最小の断片 を抜き出して紹介します。
すべてのコードは GitHub に公開しており、
👉 src/presentation / application / domain / infrastructure がレイヤーごとに分かれています。
フルコードはこちら:
処理イメージ
※このシーケンス図は、レイヤードの「典型的な流れ」を示したイメージです。今回の最小サンプルコードでは、理解しやすくするために Domain でのバリデーション処理は省略し、エンティティ中心の“薄い Domain”構成にしています。
実装
📁 ディレクトリ例
GitHub のサンプルと同じ構造は以下の通りです:
src/
presentation/
controller.py # UI層(Web API / CLI などの入り口を想定)
application/
user_service.py # ユースケース実装
domain/
user.py # エンティティ(User)
infrastructure/
user_repository.py # DBアクセス(メモリDBの例)
Presentation Layer → Application Layer(Controller → Service)
GitHub では FastAPI を最小限だけ使い、UI層=HTTPハンドラとして実装しています。
# presentation/controller.py
from application.user_service import get_user as usecase_get_user
def get_user(user_id: int):
return usecase_get_user(user_id)
※最小構成のため Controller は非常に薄くしています。ハンドラの責務だけを担当し、詳しい処理はすべて Application に委譲しています。
Application Layer → Infrastructure Layer(Service → Repository)
# application/user_service.py
from infrastructure.user_repository import find_by_id
def get_user(user_id: int):
# ユースケースとして「ユーザー取得」だけに集中
# ※バリデーション/計算ロジックなどがあれば Domain に寄せる
return find_by_id(user_id)
Infrastructure Layer(Repository)
# infrastructure/user_repository.py
USERS = {
1: {"id": 1, "name": "Alice"},
2: {"id": 2, "name": "Bob"},
}
def find_by_id(user_id: int):
# 技術的詳細(DBアクセス)はここに閉じ込める
return USERS.get(user_id)
サンプルコードでも示した通り、 「UI → ユースケース → ドメイン → インフラ」 という流れが崩れないことがレイヤードの強みです。
なお今回の最小サンプルでは、理解しやすくするため
Domain Layer は “薄く” (エンティティ中心)に構成 しています。
本格的な業務ロジックは次回扱う Clean / Hexagonal / DDD の文脈で
Domain に寄せていくイメージを掴むとより理解しやすくなります。
このように、まずは「層ごとの責務」と「依存方向」に集中してから、少しずつ Domain を“太らせていく”ほうが学習の負荷も低くなります。
📦 サンプルコード(GitHub)
本記事で紹介したレイヤードアーキテクチャの 完全なサンプルコード は
GitHub リポジトリに公開しています:
🔗 https://github.com/naokky-tech/sample-architecture-journey/tree/main/samples/layered/simple-cli
ローカルでもすぐ動かせるよう、CLI で実行可能な最小構成になっています。
👍 レイヤードのメリット
1. どこに書くか迷わない
UI? → Presentation
処理の流れ? → Application
ビジネスロジック? → Domain
DB? → Infrastructure
これだけで「どこに書くか迷う問題」が劇的に減ります。
2. 小〜中規模にはとても強い
個人開発や初期フェーズでは、まずレイヤードを選ぶのがもっとも安定します。
3. テストしやすい
部品が分かれているため、サービス層のモックが簡単に作れる。
⚠️ レイヤードの限界(次章へのブリッジ)
1. 横の依存関係が増えやすい
Application Layer に処理が集中し(いわゆる “サービス肥大化”)、
結果として “レイヤー崩壊(境界が曖昧になる)” が起きやすくなります。
2. ドメイン境界が見えにくい
あくまで“層”での分割なので、
ビジネス的な意味の境界までは表現できません。
これが次回扱う
Clean Architecture / Hexagonal / DDD(ドメイン中心)
へ進むモチベーションそのものになります。
🦉 まとめ:レイヤードは“旅の最初の1ページ”
レイヤードアーキテクチャは、最初に学ぶのに最適な構造です。
- 素朴でわかりやすい
- 書く場所に迷わない
- 次のステップへの「地図」になる
AI エージェント時代のような複雑な設計に進む前に、まずはこの“基本の地図”を持っておくと理解がスムーズになります。
📎 次回予告
次回は ドメイン中心(Clean / Hexagonal / DDD) を扱います。
レイヤードでは表現しきれない“境界”をどう扱うのか?
ここから設計として一段深い世界へ入っていきます。
📚 用語集(この記事で使うレイヤー名)
-
Presentation Layer
UI や Controller が所属する層。外部入力を受け取り、Application Layer に橋渡しする役割。 -
Application Layer
アプリケーションの振る舞いやユースケースを実行する層。本記事では“薄いユースケース層”として定義。 -
Domain Layer
ビジネスロジックとエンティティの中心となる層。「アプリが何をすべきか」を表現する中核。 -
Infrastructure Layer
DB、外部API、ファイルなど技術的詳細を扱う層。Repository はここに属する。
Discussion