1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【入門】神クラスを作らないためのレイヤードアーキテクチャ

Last updated at Posted at 2026-01-20

【入門】神クラスを作らないためのレイヤードアーキテクチャ

はじめに

アプリケーション開発を学ぶ中で、気づけばすべての処理を1つのクラスに詰め込んでしまう「神クラス(God Class)」を作ってしまった経験はありませんか?

私自身、画面表示、ビジネスロジック、データベースアクセスがすべて混在したコードを書いてしまい、保守が困難になった経験があります。そんな中で出会ったのが「レイヤードアーキテクチャ」という設計手法でした。

この記事では、神クラスを防ぎ、保守しやすいコードを書くために私が学んだレイヤードアーキテクチャの基本概念や実装方法について、自分なりの理解をまとめてみました。同じように勉強中の方の参考になれば幸いです。

レイヤードアーキテクチャとは

レイヤードアーキテクチャ(Layered Architecture)は、ソフトウェアシステムを複数の階層(レイヤー)に分割して構成する設計手法です。各レイヤーは特定の責務を持ち、上位のレイヤーは下位のレイヤーのみに依存するという原則に基づいています。

基本的な構造

一般的なレイヤードアーキテクチャは以下の4層で構成されます。

┌─────────────────────────┐
│  プレゼンテーション層     │ ← UIやAPIエンドポイント
├─────────────────────────┤
│  アプリケーション層      │ ← ビジネスロジックの調整
├─────────────────────────┤
│  ドメイン層              │ ← ビジネスルールの実装
├─────────────────────────┤
│  インフラストラクチャ層   │ ← データベース、外部API等
└─────────────────────────┘

各レイヤーの役割

1. プレゼンテーション層(Presentation Layer)

ユーザーとシステムの接点となる層です。
ビュー層(View Layer)やUI層とも呼ばれます。

責務:

  • UIの表示
  • ユーザー入力の受け取り
  • バリデーション(基本的な形式チェック)

依存関係:
アプリケーション層に依存し、ドメイン層やインフラ層には直接依存しません。

具体例:

  • アプリのフォーム画面

2. アプリケーション層(Application Layer)

ビジネスロジックの流れを制御する層です。
ユースケースを実装、ドメインオブジェクトを組み合わせて、一連の処理フローを実現します。

責務:

  • ユースケースの実装
  • ドメイン層の調整

依存関係:
ドメイン層に依存し、インフラ層には直接依存しません。
上位層(プレゼンテーション層)には依存しません。

具体例:

  • ユーザー登録処理
  • 注文確定処理

3. ドメイン層(Domain Layer)

ビジネスルールの中核を担う層です。

責務:

  • ビジネスロジックの実装
  • ドメインモデルの定義
  • ビジネスルールの検証

依存関係:
インフラ層に依存します。
上位層(プレゼンテーション層、アプリケーション層)には依存しません。

具体例:

  • エンティティ(Entity)
  • 値オブジェクト(Value Object)
  • ドメインサービス(Domain Service)

4. インフラストラクチャ層(Infrastructure Layer)

技術的な実装を担当する層です。
外部システムとの連携全般を担当します。

責務:

  • データベースアクセス
  • 外部システムとの連携

依存関係:
ドメイン層のエンティティ(データ構造)に依存します。
ドメイン層のサービスクラスや上位層には依存しません。

具体例:

  • リポジトリの実装
  • Excel等への出力
  • メール送信などの処理

レイヤードアーキテクチャのメリット

1. 関心の分離

各レイヤーが明確な責務を持つため、コードの整理がしやすくなります。

悪い例(レイヤー分けなし):
画面表示のコード、ビジネスロジック、データベースアクセスがすべて1つのクラスに混在している状態。例えば、ボタンクリックのイベントハンドラの中で直接SQLを実行し、その結果を画面に表示するような実装です。

良い例(レイヤー分け):
プレゼンテーション層は画面表示のみを担当し、アプリケーション層がビジネスロジックを調整し、インフラストラクチャ層がデータベースアクセスを担当します。各層が独立しているため、どこに何が書いてあるのかが明確です。

2. 保守性の向上

変更の影響範囲が限定されるため、保守が容易になります。

変更例と影響範囲:

  • データベースをMySQLからPostgreSQLに変更 → インフラストラクチャ層のみ修正
  • UIをWebからモバイルアプリに変更 → プレゼンテーション層のみ修正
  • ビジネスルールの変更(例:消費税率の変更) → ドメイン層のみ修正

このように、変更箇所が特定のレイヤーに限定されるため、他のレイヤーへの影響を最小限に抑えられます。

3. 再利用性

下位レイヤーのコンポーネントを複数の上位レイヤーから利用できます。

具体例:
同じドメイン層とインフラストラクチャ層を、Webアプリケーション、モバイルアプリ、バッチ処理など、複数のプレゼンテーション層から利用することができます。ビジネスロジックを一度実装すれば、異なるインターフェースで再利用できるのです。

デメリット

1. オーバーエンジニアリングのリスク

小規模なアプリケーションでは、レイヤー分けが過剰になる可能性があります。

具体的な問題:
シンプルなCRUD操作(作成・読み取り・更新・削除)だけのアプリケーションで、4層すべてを厳密に分けると、かえってコードが複雑になり開発効率が落ちます。

2. パフォーマンスの懸念

レイヤー間のデータ変換により、パフォーマンスが低下する場合があります。

具体的な問題:
各レイヤーでデータ構造(DTO、エンティティなど)を変換するオーバーヘッドが発生します。特に大量のデータを扱う場合、変換処理がボトルネックになることがあります。

実装のポイント

依存関係のルール

レイヤードアーキテクチャで最も重要なのは、依存関係の方向です。

基本ルール:

  • 上位レイヤーは下位レイヤーに依存できる
  • 下位レイヤーは上位レイヤーに依存してはいけない
  • ただし例外として、インフラ層はドメイン層のエンティティ(データ構造)のみに依存します

依存関係の構造

┌─────────────────────────┐
│  プレゼンテーション層     │
└───────────┬─────────────┘
            ↓
┌───────────┴─────────────┐
│  アプリケーション層      │
└───────────┬─────────────┘
            ↓
┌───────────┴─────────────┐
│  ドメイン層              │ ←───────┐
└───────────┬─────────────┘         │
            ↓                       │
┌───────────┴─────────────┐         │
│  インフラストラクチャ層   │ ────────┘
└─────────────────────────┘
            双方向の依存
   (エンティティのみ例外的に許可)

実例:

基本原則:
プレゼンテーション層はアプリケーション層を呼び出せますが、アプリケーション層はプレゼンテーション層を知りません。これにより、UIを変更してもアプリケーション層に影響を与えずに済みます。

具体的な処理フロー(ユーザー一覧の更新):

  1. プレゼンテーション層(UI)

    • ユーザーが「リスト更新」ボタンをクリック
    • アプリケーション層のgetUserList()を呼び出す
    • 結果をUI用のDTO(Data Transfer Object)で受け取り、画面に表示
  2. アプリケーション層(ユースケース)

    • getUserList()メソッドが呼ばれる
    • ドメイン層のUserServiceを使ってユーザー情報を取得
    • エンティティをUI用のDTOに変換
    • プレゼンテーション層に返却
  3. ドメイン層(ビジネスロジック)

    • UserServiceがビジネスルールに基づいて処理
    • 例:アクティブなユーザーのみ取得する、並び順を制御する
    • インフラ層のUserRepositoryを呼び出してデータ取得
    • 取得したエンティティにビジネスロジックを適用(例:ステータス判定)
  4. インフラストラクチャ層(データアクセス)

    • UserRepositoryがデータベースにアクセス
    • SQLを実行してユーザー情報を取得
    • データベースの結果をUserエンティティ(ドメイン層のオブジェクト)に変換
    • ドメイン層に返却

このように、各レイヤーが明確な責務を持ち、上位レイヤーのみが下位レイヤーを知ることで、変更の影響範囲を限定できます。

おわりに

レイヤードアーキテクチャについて、私が学んだことをまとめてきました。

主なポイント:

  • 各レイヤーが明確な責務を持つ
  • 上位レイヤーは下位レイヤーにのみ依存する(例外あり)
  • 保守性と再利用性が向上する
  • プロジェクトの規模に応じて適用する

レイヤードアーキテクチャは万能ではありませんが、コードを整理し保守しやすくするための基本的な考え方として、とても役立つ設計手法だと感じました。
特に、すべての処理を1つのクラスに詰め込んでしまう「神クラス(God Class)」を防ぐために効果的だと思います。

また、レイヤードアーキテクチャの発展形として、
クリーンアーキテクチャ(依存性逆転の原則でドメイン層を独立させる)やドメイン駆動設計(DDD)(ビジネスの概念をコードに反映)といった手法があることも知りました。

私もまだ学習中ですが、まずはレイヤードアーキテクチャの基本をしっかり身につけることが、これらの発展的な手法を理解する土台になると思っています。同じように勉強中の方の参考になれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?