0
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?

ソフトウェアアーキテクチャの基礎⑩ 第II部 アーキテクチャスタイル 第10章 レイヤードアーキテクチャ

0
Last updated at Posted at 2026-05-25

はじめに

前章(第9章)では、モノリシックアーキテクチャ・分散アーキテクチャ・分散コンピューティングの8つの誤信を通して、「アーキテクチャは複雑性との戦いである」という点を整理しました。特に印象的だったのは、「分散化は複雑性との交換である」という本書のメッセージです。

第10章からはいよいよ、具体的な「アーキテクチャスタイル」に入っていきます。その最初に登場するのがレイヤードアーキテクチャ(Layered Architecture)です。層アーキテクチャ・3層アーキテクチャ・多層アーキテクチャなどとも呼ばれ、おそらく最も広く使われているアーキテクチャスタイルです。

なぜこれほど普及したのか

レイヤードアーキテクチャが広く普及した理由はシンプルです。分かりやすく、学習しやすく、開発しやすい構造だからです。

PresentationBusinessPersistenceDatabaseという構造は多くの開発者にとって直感的であり、UIはUI、ビジネスロジックはビジネスロジック、DBアクセスはDBアクセスというように、責務ごとに整理されています。
image.png

本書が指摘する重要な点

しかし本書は、レイヤードアーキテクチャを単純に「良い」とは説明していません。むしろ、シンプルさと引き換えにアジリティやスケーラビリティを失いやすいと指摘しています。

レイヤードアーキテクチャは最も実用的である一方、最も巨大な泥団子へ進化しやすいアーキテクチャでもあります。
シンプルな構造だからこそ、ルールを守らない・責務が漏れる・バイパスが増える・共通化しすぎるといった問題が積み重なり、気づかないうちに秩序を失っていきます。

本章の本質

良いレイヤードアーキテクチャとは、「層を分けること」ではなく、「境界を守り続けること」です。第10章ではレイヤー構造・閉鎖と開放レイヤー・アーキテクチャシンクホールアンチパターン・アーキテクチャ特性評価を通して、レイヤードアーキテクチャの本質を整理していきます。


📖ソフトウェアアーキテクチャの基礎

本書は、O’Reilly Media から出版された『Fundamentals of Software Architecture: An Engineering Approach』 の日本語版です。著者の Mark Richards と Neal Ford が、アーキテクチャを工学的視点から捉え直し、理論と実務を橋渡しする知見をまとめた一冊です。

https://www.oreilly.co.jp/books/9784873119823/

目次(全24章)

1章 イントロダクション 1.1 ソフトウェアアーキテクチャの定義
1.2 アーキテクトへの期待
1.2.1 アーキテクチャ決定を下す
1.2.2 アーキテクチャを継続的に分析する
1.2.3 最新のトレンドを把握し続ける
1.2.4 決定の順守を徹底する
1.2.5 さまざまなものに触れ、経験している
1.2.6 事業ドメインの知識を持っている
1.2.7 対人スキルを持ち合わせている
1.2.8 政治を理解し、かじ取りをする
1.3 アーキテクチャと交わるもの
1.3.1 エンジニアリングプラクティス
1.3.2 運用とDevOps
1.3.3 プロセス
1.3.4 データ
1.4 ソフトウェアアーキテクチャの法則

第I部 基礎

2章 アーキテクチャ思考 2.1 アーキテクチャと設計
2.2 技術的な幅
2.3 トレードオフを分析する
2.4 ビジネスドライバーを理解する
2.5 アーキテクティングとコーディングのバランスを取る
3章 モジュール性 3.1 定義
3.2 モジュール性の計測
3.2.1 凝集度
3.2.2 結合度
3.2.3 抽象度、不安定度、主系列からの距離
3.2.4 主系列からの距離
3.2.5 コナーセンス
3.2.6 結合度とコナーセンスのメトリクスを統合する
3.3 モジュールからコンポーネントへ
4章 アーキテクチャ特性 4.1 アーキテクチャ特性の(部分的な)リスト
4.1.1 アーキテクチャの運用特性
4.1.2 アーキテクチャの構造特性
4.1.3 アーキテクチャの横断的特性
4.2 トレードオフと少なくとも最悪でないアーキテクチャ
5章 アーキテクチャ特性を明らかにする 5.1 アーキテクチャ特性をドメインの関心事から捉える
5.2 要件からアーキテクチャ特性を抽出する
5.3 事例:シリコンサンドイッチ
5.3.1 明示的な特性
5.3.2 暗黙的な特性
6章 アーキテクチャ特性の計測と統制 6.1 アーキテクチャ特性の計測
6.1.1 運用面の計測
6.1.2 構造面の計測
6.1.3 プロセス面の計測
6.2 統制と適応度関数
6.2.1 アーキテクチャ特性の統制
6.2.2 適応度関数
7章 アーキテクチャ特性のスコープ 7.1 結合とコナーセンス
7.2 アーキテクチャ量子と粒度
7.2.1 事例:Going、Going、Gone
8章 コンポーネントベース思考 8.1 コンポーネントの分類
8.2 アーキテクトの役割
8.2.1 アーキテクチャの分割
8.2.2 事例:シリコンサンドイッチにおける分割
8.3 開発者の役割
8.4 コンポーネントを識別する流れ
8.4.1 初期コンポーネントを識別する
8.4.2 コンポーネントに要件を割り当てる
8.4.3 ロールや責務を分析する
8.4.4 アーキテクチャ特性を分析する
8.4.5 コンポーネントを再構成する
8.5 コンポーネントの粒度
8.6 コンポーネント設計
8.6.1 コンポーネントの発見
8.7 事例:「Going、Going、Gone」におけるコンポーネントの発見
8.8 アーキテクチャ量子再び:モノリシックアーキテクチャと分散アーキテクチャの選択

第II部 アーキテクチャスタイル

9章 基礎 9.1 基礎的なパターン
9.1.1 巨大な泥団子
9.1.2 ユニタリーアーキテクチャ
9.1.3 クライアント/サーバー
9.2 モノリシックアーキテクチャと分散アーキテクチャ
9.2.1 誤信1:ネットワークは信頼できる
9.2.2 誤信2:レイテンシーがゼロ
9.2.3 誤信3:帯域幅は無限
9.2.4 誤信4:ネットワークは安全
9.2.5 誤信5:トポロジーは決して変化しない
9.2.6 誤信6:管理者は一人だけ
9.2.7 誤信7:転送コストはゼロ
9.2.8 誤信8:ネットワークは均一
9.2.9 分散コンピューティングにおけるその他の考慮事項
10章 レイヤードアーキテクチャ 10.1 トポロジー
10.2 層の分離
10.3 レイヤーの追加
10.4 その他の考慮事項
10.5 このアーキテクチャスタイルを採用する理由
10.6 アーキテクチャ特性の評価
11章 パイプラインアーキテクチャ 11.1 トポロジー
11.1.1 パイプ
11.1.2 フィルター
11.2 事例
11.3 アーキテクチャ特性の評価
12章 マイクロカーネルアーキテクチャ 12.1 トポロジー
12.1.1 コアシステム
12.1.2 プラグインコンポーネント
12.2 レジストリ
12.3 コントラクト
12.4 事例とユースケース
12.5 アーキテクチャ特性の評価
13章 サービスベースアーキテクチャ 13.1 トポロジー
13.2 トポロジーの種類
13.3 サービスの設計と粒度
13.4 データベース分割
13.5 アーキテクチャ例
13.6 アーキテクチャ特性の評価
13.7 このアーキテクチャスタイルがふさわしいとき
14章 イベント駆動アーキテクチャ 14.1 トポロジー
14.2 ブローカー
14.3 メディエーター
14.4 非同期の能力
14.5 エラー処理
14.6 データロスの防止
14.7 ブロードキャスト能力
14.8 リクエスト・リプライ
14.9 リクエストベースとイベントベースの間を取る
14.10 ハイブリッドなイベント駆動アーキテクチャ
14.11 アーキテクチャ特性の評価
15章 スペースベースアーキテクチャ 15.1 一般的なトポロジー
15.1.1 処理ユニット
15.1.2 仮想ミドルウェア
15.1.3 データポンプ
15.1.4 データライター
15.1.5 データリーダー
15.2 データ衝突
15.3 クラウドとオンプレミス
15.4 レプリケーションキャッシュと分散キャッシュ
15.5 ニアキャッシュの考慮
15.6 実装例
15.6.1 コンサートチケット販売システム
15.6.2 オンラインオークションシステム
15.7 アーキテクチャ特性の評価
16章 オーケストレーション駆動サービス指向アーキテクチャ 16.1 歴史と哲学
16.2 トポロジー
16.3 分類
16.3.1 ビジネスサービス
16.3.2 エンタープライズサービス
16.3.3 アプリケーションサービス
16.3.4 インフラストラクチャサービス
16.3.5 オーケストレーションエンジン
16.3.6 メッセージフロー
16.4 再利用...と結合
16.5 アーキテクチャ特性の評価
17章 マイクロサービスアーキテクチャ 17.1 歴史
17.2 トポロジー
17.3 分散
17.4 境界づけられたコンテキスト
17.4.1 粒度
17.4.2 データ分離
17.5 API層
17.6 運用面での再利用
17.7 フロントエンド
17.8 通信
17.8.1 コレオグラフィとオーケストレーション
17.8.2 トランザクションとサーガ
17.9 アーキテクチャ特性の評価
17.10 参考文献
18章 適切なアーキテクチャスタイルを選ぶ 18.1 アーキテクチャにおけるトレンドの変遷
18.2 判断基準
18.3 モノリスの事例:シリコンサンドイッチ
18.3.1 モジュラーモノリス
18.3.2 マイクロカーネル
18.4 分散型のケーススタディ:Going、Going、Gone

第III部 テクニックとソフトスキル

19章 アーキテクチャ決定 19.1 アーキテクチャ決定に関するアンチパターン
19.1.1 資産防御アンチパターン
19.1.2 グラウンドホッグデーアンチパターン
19.1.3 メール駆動アーキテクチャアンチパターン
19.2 アーキテクチャ上重要なもの
19.3 アーキテクチャデシジョンレコード
19.3.1 基本構造
19.3.2 ADRを保存する
19.3.3 ドキュメントとしてのADR
19.3.4 標準のためにADRを用いる
19.3.5 事例
20章 アーキテクチャ上のリスクを分析する 20.1 リスクマトリックス
20.2 リスクアセスメント
20.3 リスクストーミング
20.3.1 特定
20.3.2 合意
20.3.3 軽減
20.4 ユーザーストーリーリスク分析
20.5 リスクストーミング例
20.5.1 可用性
20.5.2 弾力性
20.5.3 セキュリティ
21章 アーキテクチャの図解やプレゼンテーション 21.1 図解
21.1.1 ツール
21.1.2 標準ダイアグラム:UML、C4、ArchiMate
21.1.3 図解ガイドライン
21.2 プレゼンテーション
21.2.1 時間を操る
21.2.2 段階的な構築
21.2.3 インフォデッキとプレゼンテーション
21.2.4 スライドは物語の半分
21.2.5 不可視化
22章 効果的なチームにする 22.1 チーム境界
22.2 アーキテクトのパーソナリティ
22.2.1 コントロールフリーク
22.2.2 アームチェアアーキテクト
22.2.3 効果的なアーキテクト
22.3 どうやって管理する?
22.4 チームの警告サイン
22.5 チェックリストの活用
22.5.1 開発者のコード完成チェックリスト
22.5.2 ユニットテストと機能テストのためのチェックリスト
22.5.3 ソフトウェアリリースのためのチェックリスト
22.6 ガイダンスの提供
22.7 まとめ
23章 交渉とリーダーシップのスキル 23.1 交渉とファシリテーション
23.1.1 ビジネスステークホルダーとの交渉
23.1.2 他のアーキテクトとの交渉
23.1.3 開発者との交渉
23.2 リーダーとしてのソフトウェアアーキテクト
23.2.1 アーキテクチャの4つのC
23.2.2 プラグマティックでありながらもビジョナリーであること
23.2.3 手本を示してチームをリードする
23.3 開発チームに溶け込む
23.4 まとめ
24章 キャリアパスを開く 24.1 20分ルール
24.2 パーソナルレーダーの開発
24.2.1 ThoughtWorksテクノロジーレーダー
24.2.2 オープンソースのビジュアライゼーションビット
24.3 ソーシャルメディアの使用
24.4 別れの挨拶

付録A 自己評価のためのチェックリスト
参考文献
訳者あとがき
索引
関連書籍

10.1 トポロジー

レイヤードアーキテクチャを理解するうえで最初に重要になるのが「トポロジー(Topology)」です。ここでいうトポロジーとは、システムをどのような層構造で配置するかを意味します。レイヤードアーキテクチャではシステムを複数のレイヤーへ分割し、それぞれに異なる責務を持たせます。

標準的な4層構造

最も代表的な構造は以下の4層です。

  • Presentation Layer(プレゼンテーション層) はユーザーとのやり取りを担当します。UI・HTTP受付・入力チェック・View制御が役割であり、Controller・REST API・GraphQL Endpointが該当します。

  • Business Layer(ビジネス層) はシステムの中心であり、業務ロジック・ワークフロー・ルール管理を担います。注文処理・決済処理・在庫計算などがここに位置します。

  • Persistence Layer(永続化層) はデータアクセスを担当します。DBアクセス・ORM・Repositoryパターンがその役割であり、JPA・MyBatis・Repositoryクラスが該当します。

  • Database Layer(データベース層) はデータの永続化・管理・トランザクションを担います。

この構造の本質:関心の分離

この構造で最も重要なのが「関心の分離(Separation of Concerns)」です。UIの責務・業務ロジックの責務・DBアクセスの責務を明確に分けることで、たとえばUI変更がビジネス層や永続化層に影響を与えにくくなり、保守性が向上します。

技術による分割

本書では、レイヤードアーキテクチャは「技術による分割」であると説明されています。UI・Business・DBというように技術責務の単位で分割するこのアプローチは、第8章で扱ったOrder・Payment・Shippingのようなドメイン分割とは対照的です。

この違いは実務上の問題として現れます。注文機能を変更したい場合、レイヤードアーキテクチャではController・Service・Repository・DBと複数の層を横断して修正が必要になります。一方、ドメイン分割であればOrderコンポーネント内に変更が局所化されます。レイヤードアーキテクチャは技術的な整理には強い一方、変更の局所化は苦手という特性を持ちます。
image.png


論理トポロジーと物理トポロジー

重要な点として、「論理構造」と「物理構造」は別物です。Presentation・Business・Persistenceという論理的な責務分離は設計上の話であり、物理的には単一プロセス・単一サーバーへのデプロイ、すなわちモノリシックな構成であることが多くなります。

レイヤードアーキテクチャが広く使われる理由 本書では、このスタイルが広く採用される理由として、分かりやすさ・開発のしやすさ・IDEとの相性の良さ・小規模から中規模のシステムへの適性・チームへの教育のしやすさが挙げられています。Spring Bootにおけるcontroller・service・repository・entityというパッケージ構成や、ASP.NETにおけるControllers・Services・Repositoriesという構成は、その典型例です。

巨大化のリスク

本書は同時に、レイヤードアーキテクチャが巨大化しやすいことも強調しています。Controller・Service・Repository・DBという流れが増え続けると、レイヤーを横断する変更・パススルー・共通化の肥大化・密結合が積み重なり、巨大な泥団子へと近づいていきます。

10.1のまとめ

  • レイヤードアーキテクチャは最も普及したアーキテクチャスタイルであり、標準的には4層構造を取る
  • 関心の分離が最大の特徴であり、技術責務による分割を行う
  • 小規模から中規模のシステムでは非常に強力な選択肢である
  • ドメイン分割と異なり、変更の局所化が苦手という特性を持つ
  • シンプルさゆえに巨大化しやすく、境界を守り続けることが重要である

10.2 層の分離

前節では、Presentation・Business・Persistence・Databaseというレイヤードアーキテクチャの基本構造を見てきました。しかし、「層を分ける」だけでは良いレイヤードアーキテクチャにはなりません。本書で特に重要視されているのが各レイヤー間をどれだけ厳密に分離するかという問いです。

・ 閉鎖レイヤー(Closed Layer)

閉鎖レイヤーとは、「必ず順番に通過するレイヤー
」です。Presentation・Business・Persistence・Databaseという順で、PresentationからDBへの直接アクセスは禁止され、必ず中間レイヤーを経由することが強制されます。

なぜ閉じるのかといえば、責務の境界を守るためです。たとえばDB構造の変更が生じた場合、Persistence Layerだけを修正することでPresentation・Business Layerへの影響を抑えられます。閉鎖レイヤーのメリットとして、保守のしやすさ・依存関係の明確化・ルールの強制・コナーセンスの抑制が挙げられます。

一方で問題もあります。本書では、閉鎖レイヤーにはパフォーマンス上の問題があると説明されています。単純な参照処理でもController・Service・Repository・DBのすべてを通過する必要があり、Serviceが return repository.findById(id) を返すだけのパススルー状態になりがちです。こうした「ただ通過するだけ」の構造が積み重なると、後述するアーキテクチャシンクホールへとつながります。

image.png

・ 開放レイヤー(Open Layer)

開放レイヤーとは、「レイヤーをバイパス可能」な構造です。たとえばPresentationからPersistenceへ、Businessレイヤーを飛ばして直接アクセスすることを許容します。

主な目的はパフォーマンスの改善です。都道府県一覧やカテゴリ一覧のような単純なマスタデータ取得では業務ロジックが不要であり、すべての層を通過することは非効率です。開放レイヤーによって高速化・シンプル化・不要なレイヤーの回避が可能になります。

しかし本書では、開放レイヤーを多用するとレイヤードアーキテクチャが崩壊すると警告しています。ControllerからDBへの直接アクセスが複数箇所で発生すると、どこからでもDBにアクセスできる状態になり、巨大な泥団子へと近づいていきます。
image.png

・ 隔離(Isolation)としてのレイヤー

本書では、レイヤーの重要な役割として「隔離(Isolation)」も説明されています。たとえばMySQLからPostgreSQLへのDB移行が生じた場合、Persistence Layerで変更を吸収できれば、Business Layerへの影響を最小限に抑えられます。レイヤーとは責務の境界であると同時に、変更を閉じ込めるための隔離の仕組みでもあります。
image.png

バイパスの危険性

レイヤーのバイパスが増えると依存関係が不明確になります。ControllerへのSQL直書き・UIからのRepository直接呼び出し・共通Utilを経由したDBアクセスといった実務でよく見られるアンチパターンは、いずれもレイヤーの崩壊を招きます。

本書は「閉鎖レイヤーが絶対正義」とは述べていません。重要なのは「どこを閉じるか」の判断です。業務処理は厳密に閉鎖で管理し、読み取り専用の処理は開放で軽量化するといった使い分けが、柔軟性と構造維持のトレードオフを適切に扱うことにつながります。

10.2 まとめ

  • 閉鎖レイヤーは順番通過を強制し、保守性に強い
  • 開放レイヤーはバイパスを許容し、柔軟性とパフォーマンスに強い
  • バイパスしすぎると責務崩壊・密結合・コナーセンスの増加を招く
  • レイヤーの本質は「変更の隔離」であり、依存方向を制御することが良いレイヤードアーキテクチャの核心である

10.3 レイヤーの追加

前節では、閉鎖レイヤー・開放レイヤー・レイヤーの分離について整理しました。しかし実際のシステムでは、最初に設計したレイヤー構造のまま運用され続けることはほとんどありません。機能追加やシステムの成長に伴って、新しいレイヤーが追加されていくからです。

本節では、レイヤードアーキテクチャが成長する過程で発生するサービス層の追加・共通オブジェクトの問題・レイヤー管理の複雑化について整理していきます。

サービス層の追加

レイヤードアーキテクチャで最もよく追加されるのが**「サービス層(Service Layer)」**です。

初期はPresentation・Persistence・Databaseというシンプルな構造でも、ビジネスロジックが増え始めるとControllerへの業務処理の集中が起きます。その解決策としてサービス層が追加され、Presentation・Service・Persistence・Databaseという4層構造へと発展します。

サービス層の役割は業務ロジックの集約・ワークフロー制御・トランザクション制御・ドメインルールの管理です。Controllerに if 文・update 処理・メール送信・バリデーションが混在するFat Controllerの状態を解消し、OrderService・PaymentServiceといった形で責務を整理することが目的です。

・ レイヤー増殖問題

しかし本書では、サービス層の追加によってレイヤーが増殖しやすくなると説明されています。Controller・ApplicationService・DomainService・Repository・DAO・Databaseというように層が増え続けることがよくあります。

問題はその内実です。層は増えているにもかかわらず、実際にはすべてのレイヤーがそのまま処理を次の層へ流すだけのパススルー状態になることがあります。DTO・Facade・Manager・Service・Helper・Repository・DAOと構造だけが複雑になる一方、各層に実質的な処理がない「設計している感だけが増える」状態です。

本書ではこれを「アーキテクチャシンクホールアンチパターン」へつながるものとして説明しています。
各レイヤー内でビジネスロジックが実行されず、リクエストがパススルーされてレイヤー間を移動するだけの状態がシンクホールです。
image.png

・ 共通オブジェクトの問題

次に問題となるのが**「共通オブジェクト」**です。UserDTO・CommonResult・BaseEntity・SharedUtilのような共通オブジェクトは、「再利用したい」という開発者の自然な動機から増えていきます。

しかし本書では、共通オブジェクトの乱用はレイヤー間の結合を強めると説明されています。Presentation・Business・Persistenceのすべてで同じDTOを使用すると、UI要件の変更がPersistence層にまで影響を及ぼします。共通化はコナーセンスの増加を意味し、GlobalHelper・CommonManager・SharedUtilsのような共通化の連鎖は巨大な泥団子への入口となります。共通化と結合はトレードオフの関係にあることを忘れてはなりません。

・ レイヤー管理の複雑化

レイヤーが増えると管理コストも増大します。どこからどこへ依存してよいかの管理・Entity・DTO・ViewModelの間の変換・トランザクション境界の定義といった課題が複雑に絡み合います。

本書では、レイヤーを増やすことは必ずしも良い設計ではないと説明されています。層が多いことは高品質を意味しません。重要なのは**「そのレイヤーに存在理由があるか」**という問いです。

良いレイヤーの追加とは、明確な責務・変更の境界・コナーセンスの低下・隔離の価値を持つものです。レイヤーは「増やす」ものではなく、「責務を隔離するために存在する」ものです。

10.3 まとめ

  • システムの成長とともにレイヤーは増えやすく、サービス層の追加は業務ロジックの整理に有効である
  • 一方でレイヤーの増殖によりパススルー問題が発生し、アーキテクチャシンクホールへとつながる
  • 共通オブジェクトの乱用はレイヤー間の結合を強め、コナーセンスを増加させる
  • レイヤーの追加には明確な存在理由が必要であり、層が多いことは高品質を意味しない
  • レイヤー追加は複雑性の追加でもあり、柔軟性と理解コストのトレードオフを伴う

10.4 その他の考慮事項

ここまで見てきたように、レイヤードアーキテクチャは分かりやすさ・学習のしやすさ・シンプルさ・開発のしやすさという強力なメリットを持っています。しかし本書では、レイヤードアーキテクチャには構造的に発生しやすい問題があることも強調されています。本節では、アーキテクチャシンクホールアンチパターン・パススルー問題・レイヤードアーキテクチャの限界について整理します。

アーキテクチャシンクホールアンチパターン

本章で最も重要なアンチパターンが「アーキテクチャシンクホール(Architecture Sinkhole)」です。一言でいえば、「レイヤーを大量に通過しているのに、ほとんど何もしていない状態」です。

Controller・Service・Repository・DAO・Databaseという構造は一見きちんと層分離されているように見えます。しかし実際には、ControllerはServiceを呼ぶだけ、ServiceはRepositoryを呼ぶだけ、RepositoryはDAOを呼ぶだけ、という全レイヤーを「通過するだけ」の状態になっていることがあります。

本書では、アーキテクチャシンクホールは不要な抽象化を大量に生むと説明されています。結果としてコード量の増加・理解コストの増加・デバッグの困難化・パフォーマンスの低下・変更箇所の増加といった問題が生じます。構造だけが複雑で中身が薄い状態です。

Serviceが return repository.findAll() を返すだけ、DTO変換層がEntityをDTOに変換するだけというケースは実務でもよく見られます。これらは「意味のない層」の典型例です。

なぜこうした状態が発生するかといえば、「レイヤードだからすべての層を通すべき」という思い込みによって、構造の維持が目的化してしまうからです。本書は、レイヤーは「存在すること」ではなく「責務を持つこと」に意味があると説明しています。


パススルー問題

アーキテクチャシンクホールと密接に関係するのがパススルー問題です。データをそのまま次の層へ流すだけの処理が連鎖する状態を指します。

パススルーが問題となる理由は、仕様変更の際にメソッドの引数が変わると全レイヤーの修正が必要になるためです。これは強いコナーセンスを生みます。RequestDTO・ServiceDTO・PersistenceDTO・Entityと連なる「変換のための変換」も、パススルー問題の典型的な現れ方です。

本書は、層を増やすほど良いわけではなく、意味のない層は複雑性を増やすだけであると警告しています。

レイヤードアーキテクチャの限界

本書では、レイヤードアーキテクチャには構造的な限界があると説明されています。

  • スケーラビリティの限界として、レイヤードアーキテクチャは通常単一デプロイであるため、一部に高負荷が発生しても全体をスケールする必要があり非効率です。

  • パフォーマンスの限界として、閉鎖レイヤーではすべての層を通過するため、不要な処理・DTO変換・オブジェクト生成によるオーバーヘッドが増加します。^

  • 変更影響範囲の問題として、技術責務による分割であるため、Order機能の変更一つでUI・Service・Repository・DBのすべてにわたる横断的な変更が必要になります。

  • ドメイン分離の弱さとして、UI・Business・DBという技術分割では、Order・Payment・Shippingといった業務境界での分離が難しく、現代の大規模システムでは対応が困難になります。

これらの限界から、システムが成長するにつれてService・共通Util・DTO・レイヤーが増殖し、巨大な泥団子へと近づきやすいという本書の指摘は、実務でも非常によく当てはまります。

ではレイヤードアーキテクチャはダメなのか?

本書はレイヤードアーキテクチャが古いとは述べていません。小規模から中規模のシステムでは非常に合理的であり、初期開発に強く、チームへの教育もしやすい。実務では今でも主流のアーキテクチャスタイルです。

本節の核心は、**「レイヤードアーキテクチャはシンプルだからこそ腐りやすい」**という点です。ルールを守らないことでレイヤーが形骸化し、パススルーが増加し、シンクホール化し、巨大な泥団子へと至る流れは非常によく見られます。

良いレイヤードアーキテクチャとは、層を増やすことではなく、不要な複雑性を増やさないことです。

10.4 まとめ

  • アーキテクチャシンクホールは「意味のない通過」が積み重なった状態であり、不要な抽象化を生む
  • パススルーは強いコナーセンスを生み、変更の影響範囲を広げる
  • レイヤードアーキテクチャにはスケーラビリティ・パフォーマンス・変更影響・ドメイン分離の面で構造的な限界がある
  • 一方で小規模から中規模のシステムでは依然として強力な選択肢である
  • 層の形骸化を防ぎ、各レイヤーに明確な存在理由を持たせ続けることが重要である

10.5 このアーキテクチャスタイルを採用する理由

ここまで見てきたように、レイヤードアーキテクチャにはシンクホール問題・パススルー問題・スケーラビリティの限界・密結合化といった弱点があります。では「レイヤードアーキテクチャは時代遅れなのか」というと、本書の答えは明確に「NO」です。本書でも、レイヤードアーキテクチャは現在でも最も広く使われているアーキテクチャスタイルの一つと説明されています。問題があるにもかかわらず広く使われ続けているのには、明確な理由があります。

1.小規模から中規模への適性

本書がまず強調するのが、小規模から中規模のシステムとの相性の良さです。システム全体を理解しやすく、依存関係が直感的で、少人数のチームでも管理でき、開発スピードを出しやすいという特性があります。

社内システム・管理画面・MVP・PoC・スタートアップの初期フェーズといったケースでは、分散化するメリットが薄く、むしろシンプルなレイヤードの方が速く開発できます。

2.シンプルさという武器

本章を通じてレイヤードアーキテクチャの最大の強みとして繰り返し登場するのが**「シンプルさ」**です。Presentation・Business・Persistenceという構造は誰でも理解でき、新規参画者も「どこに何を書くか」が分かりやすい。本書でも、理解しやすさは大きな武器であると説明されています。

また、Spring Bootのcontroller・service・repository、ASP.NETのControllers・Services・Repositories、RailsのMVCなど、現代の主要フレームワークの多くがレイヤード構造を前提として設計されており、IDEやフレームワークとの相性も非常に良い点が挙げられます。

3.コスト効率の良さ

本書では、レイヤードアーキテクチャはコスト効率が良いとも説明されています。モノリシックな構成であれば1アプリ・1DBというシンプルなインフラで済み、Service Discovery・API Gateway・Message Broker・分散トレーシングといった分散システム特有の仕組みが不要です。少人数チームでも十分に運用できます。

4.初期フェーズとの相性

本書では、要件が不確実な初期フェーズにおいてレイヤードアーキテクチャが非常に有効と説明されています。仕様変更が頻発する状況でも、単一デプロイであればすべてを一気に修正でき、初速を出しやすいためです。

逆に、最初からマイクロサービス化するとAPI設計・契約管理・分散監視・CI/CD・データ整合性といった複雑性を先に抱え込むことになります。開発よりもインフラに時間が消えるという状況は実務でもよく見られます。複雑な問題に複雑な解決策を持ち込まないことが、初期フェーズでは特に重要です。

5.適材適所という考え方

本書が一貫して伝えるのは、レイヤードアーキテクチャは「悪いアーキテクチャ」ではなく、多くの状況では合理的な選択であるという点です。

「分散=モダン、モノリス=古い」という単純な図式は危険です。重要なのはシステムの特性に合っているかどうかです。小規模・少人数・MVPの段階ではレイヤードが適しており、高いスケーラビリティや独立したチームによる開発が求められる場面では分散が向いています。アーキテクチャ選定で最も危険なのは、「流行で選ぶこと」です。Kubernetesを使いたい・マイクロサービスをやりたい・イベント駆動が流行っているといった理由で選択することは、目的と手段が逆転しています。

10.5 まとめ

  • レイヤードアーキテクチャは弱点を持ちながらも現在でも最も広く使われているスタイルの一つである
  • シンプルさ・理解のしやすさ・フレームワークとの相性の良さが最大の強みである
  • 小規模から中規模のシステムや初期フェーズでは非常に合理的な選択である
  • 分散アーキテクチャは常に正解ではなく、アーキテクチャはトレードオフである
  • 良いアーキテクチャとは最もモダンなものではなく、要求に最も適したものである

10.6 アーキテクチャ特性の評価

ここまで、レイヤー構造・閉鎖レイヤー・開放レイヤー・シンクホールアンチパターン・レイヤードアーキテクチャの限界について見てきました。本節では「レイヤードアーキテクチャはどのような特性に強く、何に弱いのか」を整理します。本書では各アーキテクチャスタイルをアーキテクチャ特性の観点から評価しており、この構造が何に向いていて何に向いていないかを明確にしています。

・ デプロイ容易性(Deployability)

レイヤードアーキテクチャはモノリシック構成であることが多いため、デプロイ構造自体はシンプルです。単一アプリをデプロイするだけで済み、CI/CDの構成も比較的単純です。一方で、小さな変更であっても全体を再デプロイする必要があり、デプロイの粒度が大きいという問題があります。

・ テスト容易性(Testability)

レイヤードアーキテクチャはテストしやすい構造です。責務が分離されているため、Controller・Service・Repositoryといったレイヤー単位でのテストが可能です。Repository層をモック化したユニットテストとの相性も良く、Spring・ASP.NET・Djangoのようなレイヤードアーキテクチャを前提としたフレームワークとの組み合わせでは特に強みを発揮します。

・ モジュール性(Modularity)

モジュール性については評価が分かれます。レイヤーごとに責務分離されている点はメリットですが、技術責務による分割であるため、業務上の変更が複数レイヤーを横断しやすいという問題があります。Order機能の変更一つでController・Service・Repositoryのすべてを修正する必要が生じるため、ドメインレベルでの変更の局所化は苦手です。

・ 信頼性(Reliability)

単一プロセスであることが多いため、ネットワーク越しの通信障害や分散システム特有の障害が少なく、ACIDトランザクションを活用しやすいという強みがあります。一方で、アプリケーションが停止するとすべての機能が停止するという単一障害点の問題があり、障害の影響範囲が大きくなります。

・ パフォーマンス(Performance)

本書では、レイヤードアーキテクチャのパフォーマンスはあまり高くないと説明されています。閉鎖レイヤーの構造上すべての層を通過する必要があり、DTO変換・ORM変換・パススルー処理によるオーバーヘッドが発生します。高負荷なAPIでは特にボトルネックになりやすく、大規模システムでは問題が顕在化しやすい特性です。

・ スケーラビリティ(Scalability)

本書での評価が特に低いのがスケーラビリティです。通常は単一デプロイであるため、検索処理だけに負荷が集中している場合でも全体をスケールする必要が生じます。マイクロサービスであれば検索サービスだけを独立してスケールできるのに対し、レイヤードアーキテクチャではそうした柔軟な対応が難しくなります。

・ シンプルさ(Simplicity)

これはレイヤードアーキテクチャ最大の強みです。Presentation・Business・Persistenceという構造は直感的で誰でも理解しやすく、新規参画者の教育もしやすい。IDEとの相性も良く、本書でもシンプルさは大きな価値として扱われています。

・ 全体コスト(Overall Cost)

レイヤードアーキテクチャは比較的低コストなアーキテクチャです。1アプリ・1DBというシンプルなインフラで済み、Service Discovery・分散監視といった仕組みが不要で運用が単純です。少人数チームでも十分に運用できます。ただし、システムが巨大化すると保守・修正・リファクタリングのコストが増大し、巨大な泥団子化のリスクが高まる点には注意が必要です。

特性の整理

本書が強調するのは「万能なアーキテクチャは存在しない」という考え方です。レイヤードアーキテクチャの強みはシンプルさ・学習のしやすさ・テスト容易性・開発速度であり、弱みはスケーラビリティ・パフォーマンス・変更の局所化です。

「レイヤードは古い」でも「マイクロサービスが最強」でもなく、重要なのはどの特性を優先するかという判断です。小規模・少人数・MVPのフェーズではレイヤードが適しており、高いスケーラビリティが求められる場面では分散が向いています。アーキテクチャスタイルは「良い悪い」で選ぶものではなく、「システムの要求特性」で選ぶものです。

10.6 まとめ

  • レイヤードアーキテクチャはシンプルさとテスト容易性に強みを持つ
  • スケーラビリティとパフォーマンスは弱く、大規模システムへの対応は苦手である
  • 小規模から中規模のシステムや初期フェーズで特に強力な選択肢となる
  • 万能なアーキテクチャは存在せず、ビジネスの要求特性に基づいて選択することが重要である
  • 良いアーキテクチャとは最もモダンな構造ではなく、要求に最も適した構造である

まとめ

第10章では、n層アーキテクチャ・3層アーキテクチャ・多層アーキテクチャとも呼ばれる**「レイヤードアーキテクチャ」**について整理しました。現在でも最も広く使われているアーキテクチャスタイルの一つです。

レイヤードアーキテクチャの基本構造

本章ではまず、Presentation・Business・Persistence・Databaseという典型的な4層構造を見てきました。ここで重要だったのが**「関心の分離(Separation of Concerns)」**です。UIはUI、業務ロジックは業務ロジック、DBアクセスはDBアクセスとして責務を分離することで、保守性と理解しやすさを高めるという考え方です。

閉鎖レイヤーと開放レイヤー 次に、閉鎖レイヤーと開放レイヤーという重要な概念を学びました。閉鎖レイヤーは必ず順番に通過することで構造の秩序を守り、開放レイヤーは必要に応じてバイパスを許容することで柔軟性とパフォーマンスを優先します。ここで見えてきたのは、アーキテクチャとは「厳密性」と「柔軟性」のバランスを取る行為であるということです。
レイヤーの追加と複雑化 本章では、システムの成長に伴うサービス層の追加・共通オブジェクトの増加・DTOの増殖についても扱いました。最初はシンプルだった構造もController・Service・Repository・DAO・Databaseと層が増殖していき、「ただ通過するだけの層」が増え始めるとアーキテクチャシンクホールが発生します。

レイヤーは「存在すること」に意味があるのではなく、「責務を持つこと」に意味があると本書は警告しています。層の形骸化がシンクホールの根本原因です。

レイヤードアーキテクチャの強みと限界 本章では、シンプルさ・学習容易性・テスト容易性・開発速度・運用コストの低さという強みを整理しました。小規模から中規模のシステム・MVP・PoC・初期フェーズでは非常に合理的な選択肢であり、「レイヤードは古い」のではなく、多くの状況で最適解になり得ます。

一方でスケーラビリティ・パフォーマンス・変更の局所化には限界があります。Order機能の変更一つでUI・Service・Repository・DBのすべてに影響が及びやすい点は、技術責務分割の構造的な弱点です。レイヤードアーキテクチャは「変更の局所化」よりも「技術責務の整理」に強いアーキテクチャといえます。

第10章を通じて本書が伝えるのは、「レイヤードアーキテクチャはシンプルだからこそ強い場面がある」という点です。同時に、シンプルだからこそ油断すると巨大な泥団子へと進化しやすいという危険性も持っています。共通化しすぎる・レイヤーを増やしすぎる・バイパスを許しすぎることが、その入口となります。

重要なのは「レイヤーを作ること」ではなく、「レイヤーの境界を守り続けること」です。良いレイヤードアーキテクチャとは、層を増やした構造ではなく、責務と依存方向を制御できている構造です。

終わりに

第9章では分散システムの複雑性を学び、第10章では最もシンプルなアーキテクチャスタイルであるレイヤードアーキテクチャを見てきました。分散は複雑すぎる・レイヤードは単純すぎるという対照的な問題を抱えるこの2つのスタイルは、アーキテクトが常に「どれだけの複雑性を受け入れるか」を選択していることを示しています。

第10章までで、モジュール性・コナーセンス・アーキテクチャ量子・分散システム・レイヤー構造というアーキテクチャ設計の基礎理論が揃いました。

次章(第11章)では、レイヤードアーキテクチャとは異なる**「パイプラインアーキテクチャ」**を扱います。データフロー・イベント処理・ストリーム処理と相性が良く、AI・データ処理・ETL・動画処理など、現代システムでも重要なスタイルです。構造中心のアーキテクチャからデータフロー中心のアーキテクチャへと議論が移っていきます。

0
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
0
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?