はじめに
第7章では、結合とコナーセンス、アーキテクチャ量子、粒度(Granularity)といった概念を通して、「どの単位でシステムを分割すべきか」を整理しました。
では、次の問いに移ります。
「実際にどうやってコンポーネントを設計するのか?」
ソフトウェアアーキテクチャを設計する際、モジュール・サービス・レイヤー・マイクロサービスなど、さまざまな単位が登場します。しかし実際の開発現場では、どこで責務を分けるべきか、どの機能を同じ単位にまとめるべきか、どこまで分割すべきかという判断に悩む場面が多くあります。
ここで登場するのが、本章のテーマである「コンポーネントベース思考(Component-Based Thinking)」です。
コンポーネントとは何か
本書では、コンポーネントをシステムを構成する独立した配置可能単位として扱っています。つまりコンポーネントとは、単なるコードのまとまりではありません。独立して変更・理解・デプロイできる、アーキテクチャ設計における重要な単位です。
本章で扱うこと
本章では、コンポーネント設計について以下の観点から整理します。
① コンポーネントの分類(8.1)
ライブラリ・サブシステム・サービス・分散コンポーネントといった種別と、それぞれの役割を整理します。
② アーキテクトの役割(8.2)
技術による分割とドメインによる分割のどちらを選ぶべきかという観点から、アーキテクトの判断基準を考えます。
③ コンポーネント識別の流れ(8.4)
初期コンポーネントの決定、要件の割り当て、ロールと責務の分析、アーキテクチャ特性の分析、そして再構成というサイクルを扱います。
④ コンポーネント粒度(8.5)
分割しすぎの問題、モノリスとの境界、マイクロサービスとの違いを整理します。
⑤ コンポーネント設計(8.6〜8.7)
エンティティの罠、ワークフロー中心設計、イベントストーミング、そしてケーススタディ(Going, Going, Gone)を通して、実践的な設計手法を扱います。
この章の位置づけ
これまでの流れを振り返ると
第3章で「どう分けるか(構造)」
↓
第4章で「なぜそれを選ぶか(特性)」
↓
第5章で「どう見つけるか(抽出)」
↓
第6章で「どう守るか(維持)」
↓
第7章で「どこに適用するか(スコープ)」
を扱ってきました。
第8章はその延長として、「どう設計するか(実践的な分割)」を問います。
一言でいえば、第8章は「アーキテクチャを実際に形にする章」です。
ここからは、理論としてのアーキテクチャから、実践としてのアーキテクチャへと踏み込んでいきます。
📖ソフトウェアアーキテクチャの基礎
本書は、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 自己評価のためのチェックリスト
参考文献
訳者あとがき
索引
関連書籍
8.1 コンポーネントの分類
本書では、コンポーネントを単なるコードのまとまりではなく、「独立して配置・利用できる単位」として扱っています。
しかし実際には、「コンポーネント」と一言でいっても、その粒度や役割はさまざまです。ライブラリ・サブシステム・サービス・分散コンポーネントなど、アーキテクチャによって形は大きく変わります。
コンポーネントの代表的な分類
関数ライブラリ(Function Library)
最も小さな単位のコンポーネントです。StringUtils や DateUtils のような再利用可能な単機能のユーティリティが該当します。小さく管理しやすい反面、共通ライブラリとして肥大化すると密結合を招くという問題が実務ではよく見られます。

サブシステム(Subsystem)
複数のコンポーネントをまとめた、より大きな単位です。認証・決済・在庫といった独立した責務を持ち、内部に複数のコンポーネントを含みます。責務を整理しやすい構造である一方、境界が曖昧になり巨大化しやすい側面もあります。モジュラーモノリスでよく登場する構造です。

イベントプロセッサ(Event Processor)
イベントを受け取り処理するタイプのコンポーネントです。注文完了イベントをトリガーにメール送信・ポイント加算・在庫更新を行うような非同期・イベント駆動の処理が該当します。スケーラブルで柔軟性が高い反面、フローの追跡やデバッグが複雑になります。イベント駆動アーキテクチャにおいて重要な役割を担います。

分散サービス(Distributed Service)
独立してデプロイされるサービス単位です。注文サービス・決済サービス・在庫サービスのように、ネットワーク越しにAPI通信を行いながら独立してスケールできます。独立性が高い反面、通信コストと分散システム特有の複雑性が伴います。マイクロサービスの中心となる単位です。

コンポーネントの粒度
上記の分類が示すように、コンポーネントには小さなライブラリから大きな分散サービスまで、さまざまな粒度が存在します。コンポーネントに「絶対的な形」はなく、システムの要求とアーキテクチャスタイルに応じて適切な粒度を選択することが求められます。
実務で重要なこと
コンポーネント設計において特に重要なのは、技術だけで分けないという点です。
Controller・Service・Repositoryといった技術レイヤーで分割するアプローチはよく見られますが、これは技術都合による分割です。本来考えるべきは、注文・決済・配送といったビジネス上の責務に基づく分割です。
コンポーネントとは「責務の境界」であり、良いコンポーネント設計とはその境界を明確にすることに他なりません。コンポーネントをどう分けるかを考えることは、アーキテクチャ設計そのものといえます。
8.1のまとめ
- コンポーネントにはライブラリから分散サービスまで、さまざまな粒度がある
- コンポーネントは独立した配置可能単位であり、単なるコードのまとまりではない
- 技術レイヤーではなく、ビジネス上の責務に基づいて分割することが重要である
- コンポーネント設計はアーキテクチャ設計そのものである
8.2 アーキテクトの役割
コンポーネントベース思考において、アーキテクトの最も重要な役割の一つが「どのようにシステムを分割するかを決めること」です。
本書では、アーキテクトはアーキテクチャを構成するコンポーネントを定義し、それらをどのように分割するかを決定すると説明されています。つまりアーキテクトとは、技術選定だけを行う人でも、図を描くだけの人でもなく、「責務の境界」を設計する人です。
なぜ分割が重要なのか
コンポーネント分割は、システム全体の品質に直結します。分割が適切でなければ、変更の影響が広がり、チーム間で責務が衝突し、スケールや保守も困難になります。逆に分割が適切であれば、独立した開発・デプロイが可能になり、チームの責務が明確になります。アーキテクチャの品質は、分割の質によって大きく左右されるといえます。
2つの分割方法
本書では、コンポーネント分割には大きく2つの考え方があると説明されています。
1. 技術による分割
Presentation・Business・Persistence・Databaseのように、技術レイヤーごとに分割する方法です。レイヤードアーキテクチャで一般的なアプローチであり、構造がシンプルで多くの開発者に馴染みがあり、MVCとも相性が良いという特徴があります。

一方で本書が特に強調する問題点として、ワークフローが層を横断しやすく、変更の影響が広がりやすい点が挙げられます。注文処理を例にすると、Controller・Service・Repository・DBという流れで機能ではなく「技術」によって分かれており、ドメイン知識がシステム全体に分散してしまいます。

2. ドメインによる分割
注文・決済・配送・在庫のように、ビジネスドメインごとに分割する方法です。DDD(ドメイン駆動設計)の考え方に近く、ワークフローとの整合性が高く、変更の影響を局所化しやすいという特徴があります。

マイクロサービスとの相性も良い一方、重複コードが増える場合があり、設計難易度が高くなります。

コンウェイの法則
ここで本書が重要な視点として取り上げるのがコンウェイの法則です。
「システム構造は、その組織のコミュニケーション構造を反映する」というこの法則は、分割が技術だけで決まるわけではないことを示しています。注文チーム・決済チーム・在庫チームという組織の境界が、そのままサービスの境界になる。これがコンウェイの法則が示す現実です。

Q.どちらを選ぶべきか
本書は、技術分割とドメイン分割のどちらかが正解とは述べていません。技術分割は小規模・モノリス・シンプルな構造に向いており、ドメイン分割は大規模・分散システム・高い独立性が求められる場面に向いています。適切な分割方法は、アーキテクチャ特性と組織構造によって変わります。
事例:シリコンサンドイッチ
本書では「シリコンサンドイッチ」の事例を用いて、技術分割とドメイン分割の両方を比較しています。Inventory・Recipes・Location・Promotionというビジネス単位で分割するドメイン分割と、Common・Localという技術責務で分割する技術分割を比較した結果、ドメイン分割の方がワークフローとの整合性が高いと説明されています。

3.2のまとめ
- アーキテクトの重要な役割はコンポーネントの分割設計である
- 分割には技術による分割とドメインによる分割がある
- ドメイン分割は変更の影響を局所化しやすく、ワークフローとの整合性が高い
- コンウェイの法則が示すように、組織構造が分割に大きく影響する
- 適切な分割方法はアーキテクチャ特性と組織構造によって決まる
アーキテクトとは「境界を引く人」であり、その本質は「責務の境界をどう設計するか」を問い続けることにあります。
8.3 開発者の役割
前節では、アーキテクトの役割として「コンポーネントをどう分割するかを決めること」を整理しました。では、開発者はその中で何を担うのでしょうか。
本書では、開発者は通常アーキテクトよりも細かいレベルのコンポーネント、すなわちクラスや関数、サブコンポーネントを担当すると説明されています。アーキテクトが境界を決め、開発者がその中身を実装するという役割の違いがあります。
開発者は「設計しない」のか?
もちろん、そうではありません。アーキテクトはコンポーネントを定義しますが、実装の詳細までは決定しません。開発者はクラス設計・関数分割・実装構造・テスト設計など、コンポーネント内部の品質を支える役割を担います。
両者の視点を整理すると、アーキテクトは「どこで分けるか」「どこを独立させるか」「どの特性を優先するか」を考え、開発者は「どう実装するか」「どう保守しやすくするか」「どう品質を維持するか」を考えます。外側の構造と内側の品質、それぞれに異なる責務があります。
コンポーネント内部の責任
「注文サービス」を例に挙げると、アーキテクトが決めることはサービスとしての独立化・API境界・DB分離・他サービスとの関係です。一方、開発者が決めることはOrderServiceの設計・バリデーション・Repository構造・テスト戦略です。
内部品質の重要性
本書では、開発者に求められる重要な視点として**「コンポーネント内部の凝集性」**が挙げられています。コンポーネントの分割がいくら適切であっても、内部がスパゲッティ状態で責務が混在し依存だらけであれば意味をなしません。境界の外側だけでなく、内部設計の質も同様に重要です。
実務でよく見られる問題として、コンポーネントの境界は整理されているにもかかわらず、Utils・Helper・Manager・Commonといった責務の曖昧なクラスが内部に乱立しているケースがあります。また、開発者がアーキテクチャ構造を意識せず実装だけに集中した結果、システム全体との整合性が崩れるケースも少なくありません。
開発者に求められる視点
本書の流れを踏まえると、開発者には以下の3つの視点が求められます。
モジュール性を意識する — 高凝集・低結合を保ち、コンポーネント内部の独立性を高めます。
コナーセンスを減らす — 変更の影響を小さくし、不必要な依存を排除します。
アーキテクチャ特性を守る — パフォーマンス・保守性・テスタビリティといった特性を実装レベルで維持します。
アーキテクトと開発者の関係
アーキテクトと開発者は上下関係にあるわけではありません。本書でも、両者は協調して設計を進めるべきという考え方がベースになっています。アーキテクトが境界を定義し、開発者が内部品質を高める。両者が揃って初めて、良いアーキテクチャは成立します。
良いアーキテクチャは、良い実装によって初めて成立するものです。

8.3まとめ
- アーキテクトと開発者では担う責務が異なる
- 開発者はコンポーネント内部の設計と品質を担う
- 境界の外側だけでなく、内部品質も同様に重要である
- モジュール性やコナーセンスへの意識が開発者にも求められる
- 良い設計はアーキテクトと開発者の協調によって生まれる
8.4 コンポーネントを識別する流れ
ここまで、アーキテクトと開発者それぞれの役割、そしてコンポーネント分割の考え方を整理してきました。では、実際にどうやってコンポーネントを見つけるのでしょうか。
本書では、コンポーネント設計を一度で正解を出す作業ではないと説明しています。最初から完璧に分かるわけではなく、試行錯誤しながら調整し、何度も再構成することが前提となります。コンポーネント設計とは、正解を一発で導くものではなく、探索に近い活動です。
本書では、コンポーネント識別を以下の5つの流れで整理しています。
1. 初期コンポーネントを識別する
2. 要件を割り当てる
3. ロールと責務を分析する
4. アーキテクチャ特性を分析する
5. コンポーネントを再構成する
8.4.1 初期コンポーネントを識別する
最初に行うのは「大まかな責務の分割」です。ここで重要なのは、最初から細かく分けようとしないことです。
ECサイトであれば、まず注文・決済・在庫・配送・認証といった大きな単位で分けることから始めます。最初から細かく分けようとすると、過剰分割や責務の崩壊、マイクロサービス地獄に陥りやすくなります。
本書では、初期コンポーネントはビジネスドメインから導出されることが多いと説明されています。技術的な都合ではなく、業務単位で考えることが出発点となります。
8.4.2 コンポーネントに要件を割り当てる
次に、どの要件をどのコンポーネントが担当するかを整理します。注文作成はOrder、支払いはPayment、在庫更新はInventoryというように、責務を明確に対応づけます。
ここで注意すべきは、要件が複数のコンポーネントにまたがる場合です。これは分割が適切でなく、責務が曖昧であるか、境界の引き方が誤っている可能性を示しています。変更の境界を見直すきっかけとして捉えることが重要です。
8.4.3 ロールと責務を分析する
次のステップでは、コンポーネントの役割をさらに明確化します。たとえばOrderであれば注文受付・注文状態管理・注文履歴、Paymentであれば決済・返金・支払い検証といった具合に、各コンポーネントの責務を具体化します。
役割を明確にすることで凝集度が向上し、責務の混在を防ぐことができます。本書では、コンポーネントは単一責務に集中すべきと説明されており、高凝集を目指すことが基本方針となります。
8.4.4 アーキテクチャ特性を分析する
ここが特に重要なステップです。コンポーネントの分割は機能だけで決まるわけではありません。
たとえばPaymentには高セキュリティ・高可用性が求められ、Recommendationには高スケーラビリティ・高パフォーマンスが求められます。求められるアーキテクチャ特性が異なるコンポーネントは、分離を検討すべきです。本書では、アーキテクチャ特性はコンポーネント分割に大きな影響を与えると説明されており、第4章から第7章にかけて扱ってきた内容がここで結びつきます。
8.4.5 コンポーネントを再構成する
本書が特に強調するのが、この再構成(Refinement)のステップです。最初の分割はほぼ確実に不完全であり、再構成が前提となります。
たとえば当初は単一のOrderコンポーネントとして設計したものが、実装を進める中でOrder・OrderHistory・OrderWorkflowへと分割される、といったケースがあります。責務・通信量・コナーセンス・チームの境界は、実際に実装してみて初めて見えてくるものです。
本書では、コンポーネント識別は反復的な活動であると説明されています。一発で正解を目指すのではなく、設計は進化するものとして捉えることが重要です。
8.4のまとめ
- コンポーネント設計は反復的に行うものであり、一度で正解を出す必要はない
- 最初は粗く、業務単位で大まかに分けることから始める
- 要件と責務を割り当て、各コンポーネントの役割を明確化する
- アーキテクチャ特性の違いが分割の判断基準になる
- 実装しながら再構成することが前提であり、良い分割は育てるものである
8.5 コンポーネントの粒度
前節では「どうやってコンポーネントを識別するか」を見てきました。しかしコンポーネント設計には、もう一つ大きな難しさがあります。
「どこまで分割すべきなのか?」
これが粒度(Granularity)の問題です。本書でも、コンポーネント設計で最も難しい問題の一つが粒度であると説明されています。
粒度とは何か
粒度とは、コンポーネントをどれくらい細かく分割するかを指します。ECシステム全体を一つのコンポーネントとして扱うのが粗い粒度であり、注文・決済・配送・在庫・通知・ポイントと細かく分けていくのが細かい粒度です。
なぜ粒度が重要なのか
粒度はシステム全体の品質に直結します。
粒度が粗すぎる場合、一部の変更でも全体をデプロイする必要が生じ、スケールしづらく、障害の影響範囲も大きくなります。一方、粒度が細かすぎる場合は、サービス間の通信量が増加し、分散システム特有の複雑性が増大し、運用コストも膨らみます。粒度の選択は常にトレードオフです。
本書では、コンポーネントを細かく分割しすぎると分散アーキテクチャの複雑性が増加すると説明されています。マイクロサービス化は目的ではなく手段であり、細かく分ければ良いというわけではありません。
マイクロサービス地獄
実務でよく見られる問題として、UserNameService・UserAddressService・UserAgeServiceのように1機能を1サービスとして分割しすぎるケースがあります。結果として通信だらけになり、障害の追跡やデバッグが困難になり、チームが疲弊します。分割の本来の目的を見失った状態です。
適切な粒度とは
では、どう分ければ良いのでしょうか。本書では「変更の単位」で考えることが重要と説明されています。
Order・Payment・Inventory・Shippingのように、それぞれが独立して変更・デプロイ・スケールできる単位が理想的な粒度です。これは第7章で扱ったアーキテクチャ量子の概念、すなわち高凝集・低結合・独立デプロイという考え方と直結しています。
コナーセンスとの関係
粒度を決めるうえで本書が重視するのが3.2.5で出てきたコナーセンス(Connascence)です。一緒に変更されるものは同じコンポーネントにまとめ、独立して変更されるものは分離の候補とします。「変更の連鎖」を基準に粒度を判断するという考え方です。
粒度の判断基準
本書の流れを整理すると、以下の問いが粒度判断の基準となります。
一緒に変更されるか — YESであれば同じコンポーネントにまとめます。独立してスケールしたいか、異なるアーキテクチャ特性を持つか、チームが独立して開発するか — これらがYESであれば分離の候補となります。
技術的な都合だけで判断するのではなく、変更・スケール・デプロイの観点を組み合わせることが重要です。
分散の代償
本書では、コンポーネントを必要以上に細かくしないことが強調されています。分散化にはネットワークコスト・分散トランザクション・可観測性の低下・運用の複雑化という代償が伴います。分割の判断は、こうしたコストを十分に認識したうえで行う必要があります。
8.5のまとめ
- 粒度はコンポーネント設計における最も難しい問題の一つである
- 粗すぎても細かすぎても、それぞれ異なる問題を引き起こす
- 分割しすぎると分散アーキテクチャの複雑性が増大する
- コナーセンスが粒度判断の重要な基準となる
- 良い粒度とは、変更・スケール・デプロイの境界が一致していることである
8.6 コンポーネント設計
ここまで、コンポーネントの分類・分割方法・粒度・アーキテクチャ量子といった観点から「どう分けるか」を見てきました。では、実際にコンポーネントの中身をどう設計するのでしょうか。
本書では、ここで重要な注意点として「エンティティ中心で考えすぎないこと」を挙げています。
エンティティ中心設計の問題
多くのシステムでは、User・Order・Product・Customerのようなデータモデルを中心に設計しがちです。UserService・OrderService・ProductServiceという構造は一見整理されているように見えます。
しかし本書では、エンティティベースのコンポーネント分割はワークフローを複雑化させる場合があると指摘されています。
たとえば注文処理を考えると、Order・Customer・Payment・Inventory・Shippingとあらゆるサービスを横断する流れになりがちです。結果としてサービス間の通信が増加し、コナーセンスが強まり、ワークフロー全体が複雑化します。分散システムでは特に深刻な問題となります。
ワークフロー中心設計
本書が推奨するのがワークフロー中心設計です。これは「データ」ではなく「業務の流れ」を中心にコンポーネントを分割する考え方です。
エンティティ中心であればCustomer・Order・Productという分割になりますが、ワークフロー中心であれば注文処理・決済処理・配送処理という分割になります。本書では、コンポーネントはシステムのワークフローに沿って設計すべきと説明されており、その理由としてワークフローが変更の単位になりやすく、業務境界と一致しやすく、高凝集を実現しやすい点が挙げられています。
実務レベルで比較すると、UserService・ProductService・OrderServiceというデータ主導の設計に対し、Checkout・Fulfillment・Recommendationという業務主導の設計の方が、変更の影響を局所化しやすくなります。

イベントストーミング
本書では、ワークフローの境界を見つける方法としてイベントストーミングも紹介されています。これはドメインイベントを中心に業務を整理する手法であり、「注文された」「支払い完了」「在庫引当」「発送完了」といったイベントの流れからコンポーネントの境界を見つけていきます。
業務フローとボトルネック、責務の境界が可視化されるため、コンポーネント設計との相性が良い手法です。
コンポーネント設計はデータ設計ではない
本書が強調するのは、「コンポーネント設計はデータ設計ではない」という点です。
DBテーブルを中心にサービスを分割したり、CRUDだけを起点に考えたりするアプローチは、ワークフローの崩壊や強いコナーセンスを招くアンチパターンです。業務フローを起点に考えることが、良いコンポーネント設計の出発点となります。
また第7章で扱ったコナーセンスの観点から見ても、ワークフロー中心設計は一緒に変わるものをまとめやすく、変更の境界を明確にしやすいという利点があります。一方でエンティティ中心設計はワークフローが複数サービスに分散しやすく、変更の波及を招きやすい構造になります。
8.6のまとめ
- エンティティ中心設計はワークフローを複雑化させる場合がある
- ワークフロー中心設計は業務の流れを起点にコンポーネントを分割する
- イベントストーミングはワークフローの境界を見つける有効な手法である
- コンポーネント設計はデータ設計ではなく、変更境界の設計である
- 良いコンポーネントは「データ」ではなく「業務の流れ」によって設計される
8.7 事例:「Going, Going, Gone」におけるコンポーネントの発見
ここまで、コンポーネント分割・粒度・ワークフロー中心設計・コナーセンスといった考え方を整理してきました。本節では、本書に登場するケーススタディ「Going, Going, Gone」を通して、実際にどのようにコンポーネントを見つけていくのかを見ていきます。
Going, Going, Gone とは
本書に登場するオンラインオークションシステムのケーススタディです。商品出品・入札・落札・決済・配送という、非常に典型的な業務フローを持つシステムです。
最初にやること:業務ワークフローの整理
本書ではまず、業務ワークフローを整理するところから始めています。商品を出品する・商品を検索する・入札する・落札する・支払う・配送するといった業務イベントを並べ、システムの輪郭を掴みます。
ここで本書が強調するのは、最初から技術で分けないことです。Controller・Service・Repositoryという技術レイヤーで分割するのではなく、Auction・Bid・Payment・Shippingという業務責務の単位で考えることが出発点となります。
初期コンポーネントの発見
ワークフローから、本書では以下のようなコンポーネントを抽出しています。Auction・Bidding・Payment・User Management・Notification・Shipping・Searchです。いずれも業務単位で整理された責務です。
なぜこの分割なのか
この分割の根拠となるのが「変更の境界」です。
たとえばBiddingは入札ロジック・オークション時間・自動延長といった要素が強く連動しており、コナーセンスが強い。一方Paymentは決済・返金・支払い検証を担い、高いセキュリティ要求を持ちます。機能だけでなく、求められるアーキテクチャ特性が異なるため、両者は分離すべきコンポーネントとなります。
本書では、異なるアーキテクチャ特性を持つものは別コンポーネントに分割される傾向があると説明されています。Auctionには高パフォーマンスとリアルタイム性、Paymentには高セキュリティと高信頼性、Searchには高スケーラビリティが求められます。第4章から第7章にかけて扱ってきた内容が、ここで具体的な設計判断として結びつきます。
コンウェイの法則との関係
この事例ではチーム構造も重要な視点です。Auction Team・Payment Team・Search Teamというチーム単位での責務分割は、そのままシステム構造に反映されます。8.2節で触れたコンウェイの法則、すなわち「システム構造は組織のコミュニケーション構造を反映する」が、ここでも実際の設計判断に影響を与えています。
この事例が示す設計思想
Going, Going, Gone の事例を通じて一貫しているのは、**「業務フロー中心」**という設計思想です。重要なのはデータでも技術でもなく、ユーザーの行動と業務の変化単位です。
CRUDベースのUserService・ProductService・OrderServiceという分割はワークフローを分散させ、共通DBの使用は強いコナーセンスを生み、技術の共通化しすぎは境界を曖昧にします。これらはいずれも本書が示すアンチパターンです。
良いコンポーネント分割とは、ユーザー行動の境界を見つけることであり、業務の流れを独立した責務へ分解することです。

8.7のまとめ
- Going, Going, Gone はワークフロー中心設計の実践例である
- 技術レイヤーではなく業務責務を起点にコンポーネントを識別する
- アーキテクチャ特性の違いが分割の判断基準となる
- コンウェイの法則が示すように、チーム構造がシステム構造に影響する
- コンポーネント設計とは「変更境界」を業務の流れから発見する作業である
8.8 アーキテクチャ量子再び:モノリシックアーキテクチャと分散アーキテクチャの選択
ここまで、コンポーネントの分類・分割方法・粒度・ワークフロー中心設計・ケーススタディ(Going, Going, Gone)を通して「どう分割すべきか」を見てきました。本章の最後に、再び**アーキテクチャ量子(Architecture Quantum)**に立ち返ります。
本書では、アーキテクチャ量子はシステムをどの単位で独立させるかを考える重要な概念と説明されています。ここまでのコンポーネント設計の議論はすべて、「どこまでを一つとして扱うか」を決めるための話でもありました。そしてその問いは、現代アーキテクチャにおける最も重要な選択の一つに行き着きます。
「モノリスにすべきか、分散システムにすべきか」
モノリシックアーキテクチャ
モノリスとは、一つのアプリケーションとして一つのデプロイ単位・一つのプロセスで動作するアーキテクチャです。Order・Payment・Inventory・Shippingがすべて一体化した構造がその典型例です。
メリットとしては、デバッグやローカル実行がしやすくシンプルに開発できること、プロセス内呼び出しによる通信コストの低さ、デプロイや監視がシンプルで運用しやすい点が挙げられます。
一方デメリットとして、スケールが必要な場合は全体をスケールする必要があること、一部の障害が全体に波及しやすいこと、変更の影響範囲が広くコナーセンスが増加しやすいことが挙げられます。
分散アーキテクチャ
分散アーキテクチャとは、独立したサービスがネットワーク通信を介して連携する構造です。Order・Payment・Shippingがそれぞれ独立したサービスとして存在します。
メリットとしては、必要な箇所だけを独立してスケールできること、独立したデプロイによる柔軟性の向上、障害の影響範囲を限定できることが挙げられます。
しかし本書が特に強調するのはデメリットです。分散アーキテクチャは多くの複雑性を伴うと述べられており、ネットワーク障害・タイムアウト・分散トランザクション・可観測性の確保・データ整合性といった問題が伴います。分散化には相応の代償があります。
「マイクロサービスは常に正解ではない」
本書が繰り返し伝えるメッセージは、**「マイクロサービスは常に正解ではない」**という点です。「分散=モダン、モノリス=古い」という単純な図式は危険であり、アーキテクチャの選択はトレンドではなく、システムの要求に基づいて判断すべきものです。
量子の観点で考える
アーキテクチャ量子の観点から整理すると、モノリスは量子が大きく、分散アーキテクチャは量子が小さいといえます。つまりモノリスか分散かという選択は、量子サイズをどう設定するかという問いと同義です。
本書では、アーキテクチャ特性がモノリスか分散かを決定すると説明されています。高いスケーラビリティが必要であれば分散寄りの選択になり、シンプルさを優先すべき状況ではモノリスが適しています。小規模・初期フェーズ・少人数の開発であればモノリスが向き、大規模・高スケール・独立したチームによる開発・高い可用性が求められる場合は分散が向きます。
8.8のまとめ
- アーキテクチャ量子の概念は、モノリスか分散かという選択の基準となる
- モノリスは量子が大きく、分散アーキテクチャは量子が小さい
- 分散アーキテクチャには大きな複雑性が伴い、相応のコストがかかる
- アーキテクチャ特性がモノリスか分散かの選択を決定する
- 良いアーキテクチャとは「適切な境界」と「適切な粒度」のバランスである
モノリスか分散かは流行ではなく、システムに求められるアーキテクチャ特性によって決まります。
まとめ
第8章では、「コンポーネントをどう設計するか」というアーキテクチャ設計の実践的な部分を整理しました。本章のポイントを振り返ります。
コンポーネントとは何か(8.1)
本書ではコンポーネントを、独立して配置可能なアーキテクチャ単位として定義しています。ライブラリ・サブシステム・イベントプロセッサ・分散サービスなど、さまざまな粒度が存在しますが、いずれも共通しているのは「責務の境界」として設計されるべき単位であるという点です。
アーキテクトと開発者の役割(8.2〜8.3)
アーキテクトは境界を決め、開発者は内部品質を作ります。良いアーキテクチャは「分割」と「実装品質」の両方によって成立します。
コンポーネント識別の流れ(8.4)
本書では、初期識別・要件割り当て・責務分析・特性分析・再構成という反復的な流れが示されています。コンポーネント設計は一度で完成するものではなく、実装を進めながら繰り返し洗練させていくものです。
粒度(8.5)
粒度が粗すぎると柔軟性が低下し、細かすぎると分散アーキテクチャ特有の複雑性が増大します。粒度の選択は常にトレードオフであり、変更・スケール・デプロイの単位を基準に判断することが求められます。
コンポーネント設計(8.6)
本書では、エンティティ中心設計ではなくワークフロー中心設計が重要と説明されています。User・Product・Orderというデータ主導の分割ではなく、Checkout・Payment・Shippingという業務の流れを起点にした設計が、変更の境界を明確にしやすく高凝集を実現しやすい構造となります。
Going, Going, Gone(8.7)
ケーススタディでは、Auction・Payment・Shipping・Notificationなど、業務フローを中心にコンポーネントが抽出されました。本章全体を通じて一貫しているのは「変更の境界で分割する」という考え方です。
アーキテクチャ量子再び(8.8)
本章の最後では、モノリスと分散アーキテクチャを比較しながら「適切な量子サイズ」の重要性を整理しました。本書が述べるように、モノリスか分散かはアーキテクチャ特性によって決まります。技術トレンドではなく、システムに求められる要求特性を基準に選択することが重要です。
終わりに
第8章では、アーキテクチャをどう実際の構造へ落とし込むかを学びました。
システム設計というと、クラス図・技術選定・インフラ構成に目が向きがちです。しかし本書が一貫して伝えるのは、**「変更の境界をどう設計するか」**という問いです。一緒に変わるものをまとめ、独立して変わるものを分離し、異なる特性を持つものを分ける。これがコンポーネント設計の本質です。
また本章では、コナーセンス・粒度・ワークフロー・アーキテクチャ量子といった概念が、すべて「変更」というテーマで結びついていることも見えてきました。良いアーキテクチャとは構造が美しいものではなく、変化に耐えられる構造です。
第8章までで、モジュール性(第3章)・アーキテクチャ特性(第4章)・特性の抽出(第5章)・計測と統制(第6章)・スコープと粒度(第7章)・コンポーネント設計(第8章)という、アーキテクチャ設計の基盤部分が一通り揃いました。
次章(第9章)からはいよいよ、具体的なアーキテクチャスタイルに入ります。レイヤード・パイプライン・マイクロカーネル・サービスベース・イベント駆動・マイクロサービスなど、実際にどのような構造が存在するのかを比較しながら見ていきます。

