レイヤードアーキテクチャ#
概要#
レイヤードアーキテクチャ(Layered Architecture)は、システムを複数の階層(レイヤー)に分割する最も一般的なアーキテクチャパターンの一つ。
各レイヤーは特定の役割と責任を持ち、上位のレイヤーは下位のレイヤーのみに依存する。
典型的な4層構造#
┌─────────────────────────────┐
│ プレゼンテーション層 │ ← UI、Webコントローラー
├─────────────────────────────┤
│ ビジネスロジック層 │ ← ドメインロジック、サービス
├─────────────────────────────┤
│ データアクセス層 │ ← Repository、DAO
├─────────────────────────────┤
│ データベース層 │ ← データベース、ファイルシステム
└─────────────────────────────┘
各層の役割#
プレゼンテーション層(Presentation Layer)
ユーザーインターフェース
リクエストの受付とレスポンスの返却
入力検証
ビジネスロジック層(Business Logic Layer)
ビジネスルールの実装
データの変換と処理
トランザクション管理
データアクセス層(Data Access Layer)
データの永続化
データベース操作の抽象化
クエリの最適化
データベース層(Database Layer)
データの物理的な保存
データの整合性維持
クラス名について
※レイヤーの名前と、実装で使う名前(role)はあえて分けて抽象化する慣習がある
Layer |
Role(よく使われる名前) |
|---|---|
Presentation |
Controller / Router / Presenter |
Business Logic |
Service / UseCase |
Data Access |
Repository / DAO |
Infrastructure |
DB / API Client |
実装例(Python)#
# プレゼンテーション層
class UserController:
def __init__(self, user_service):
self.user_service = user_service
def get_user(self, user_id):
user = self.user_service.get_user(user_id)
return {"id": user.id, "name": user.name}
# ビジネスロジック層
class UserService:
def __init__(self, user_repository):
self.user_repository = user_repository
def get_user(self, user_id):
user = self.user_repository.find_by_id(user_id)
if not user:
raise ValueError("User not found")
return user
# データアクセス層
class UserRepository:
def __init__(self, db):
self.db = db
def find_by_id(self, user_id):
return self.db.query("SELECT * FROM users WHERE id = ?", user_id)
FastAPIによるAPI設計の例#
メリット / デメリット#
メリット#
関心の分離: 各層が明確な責任を持つ
理解しやすさ: 構造が単純で直感的
テスタビリティ: 各層を独立してテスト可能
保守性: 変更の影響範囲が限定される
再利用性: 下位層のコンポーネントを再利用できる
デメリット#
パフォーマンス: 層を跨ぐ呼び出しによるオーバーヘッド
密結合のリスク: 下位層への依存が強くなりがち
柔軟性の欠如: 厳格な階層構造により、変更が困難な場合がある
モノリシックになりがち: すべてが一つのデプロイメントユニットになる
ベストプラクティス#
依存関係は一方向に: 上位層から下位層への依存のみを許可
インターフェースの活用: 層間の結合度を下げる
DTOの使用: 層間でのデータ転送にはDTOを使用
トランザクション境界の明確化: ビジネスロジック層でトランザクションを管理
例外処理の統一: 各層で適切なレベルの例外処理を行う
適用場面#
レイヤードアーキテクチャが適している場合:
中小規模のWebアプリケーション
CRUD操作が中心のシステム
チームが伝統的なアーキテクチャに慣れている場合
シンプルな構造が求められる場合