はじめに
エンジニアとして経験を積むにつれ、コードだけでなく「システム全体をどう設計するか」という問いに直面する機会が増えてきました。
また、システム開発の現場で「なぜこの設計にしたのか?」と問われたとき、うまく答えられないことがありました。
フレームワークやライブラリの選定には自信があっても、アーキテクチャ全体の判断を言語化するのは難しい。
そんなときに出会ったのが本書『ソフトウェアアーキテクチャの基礎』です。
「アーキテクチャは後から変更しづらい重要な決定の集合」という定義に触れ、ようやく腑に落ちた感覚がありました。
この記事では、その学びを自分なりに整理していきます。
📖ソフトウェアアーキテクチャの基礎
本書は、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 自己評価のためのチェックリスト
参考文献
訳者あとがき
索引
関連書籍
こんな人におすすめ
- 「アーキテクト」としてのスキルを体系的に学びたいエンジニア
- プロジェクトで設計判断を任されるリーダー層
- モノリシックからマイクロサービスへの移行に関心のある開発者
- 技術選定やシステム構成のトレードオフを理解したい人
第1章イントロダクションを読む
今回は、 第1章「イントロダクション」 を要約・紹介したものになります。
「アーキテクチャって結局なんなの?」「アーキテクトってどんな役割?」といった疑問に答える導入編になっています。
1. ソフトウェアアーキテクチャの定義(1.1)
アーキテクチャには唯一絶対の定義はありません。
時代の流れと共に、ソフトウェアアーキテクトの役割が広範囲になり、さらに拡大をし変化し続けているからです。
著者はその中で次のように整理しています。
アーキテクチャとは、後から変更するのが難しい重要な決定の集合である
つまり、実装の詳細やコードレベルの設計だけでなく、システムの長期的な方向性を左右する決定そのものがアーキテクチャです。
本書では、ソフトウェアアーキテクチャを①システムの構造、システムがサポートする②アーキテクチャ特性、③アーキテクチャ決定、④設計指針の4つの組合わせで構成されているものと定義している。
①システムの構造
レイヤードアーキテクチャ(Layered Architecture)
アプリケーションを層(レイヤー)に分割し、それぞれの役割を明確にするスタイル。 典型的には「UI → ビジネスロジック → データアクセス → データベース」という構造。<メリット>シンプルで理解しやすく、多くのフレームワークで標準的に採用されている。 <デメリット>層間の依存が強くなる。大規模化すると保守性が下がる。
サービス指向アーキテクチャ(SOA: Service Oriented Architecture)(Client-Server)
サービス群が並び、メッセージバスやミドルウェア経由でつながる構造。業務単位のサービスを構築し、エンタープライズ全体で再利用する考え方。企業システム統合の文脈でよく登場。
<メリット>再利用性が高く、大規模な業務システム統合に有効
<デメリット>ESB(Enterprise Service Bus)などミドルウェア依存が大きくなる。
モノリシックアーキテクチャ(Monolithic Architecture)
アプリ全体がひとつのコードベース、プロセスとして動作。機能ごとにモジュールは分けられているが、デプロイはまとめて行う。 <メリット>開発やデプロイがシンプル。小規模システムでは効率的。 <デメリット>大規模化すると変更が困難。部分的なスケーリングが難しいマイクロサービスアーキテクチャ(Microservices Architecture)
内容 機能を小さな独立したサービスに分割し、それぞれを独立して開発・デプロイ可能にする。 サービス間は API(REST や gRPC)で通信。 <メリット>独立デプロイが可能でチーム単位の開発に向く。部分的なスケーリングが可能。 <デメリット>サービス間通信や分散管理の複雑さが増す。運用・監視のコストが高い。マイクロカーネルアーキテクチャ(Microkernel Architecture / Plugin Architecture)
コアシステム+プラグイン群が接続されている構造。基本機能は「コアシステム」にまとめ、拡張機能を「プラグイン」として追加する方式。IDE(Eclipse、IntelliJ)やCMS(WordPressなど)で用いられている。<メリット>機能拡張が容易で、コアはシンプルに保てる <デメリット>プラグイン間の依存管理が複雑になる
スペースベースアーキテクチャ(Space-Based Architecture, SBA)
<メリット>高いスケーラビリティ、高い可用性、リアルタイム性 <デメリット>設計の複雑さ、データ一貫性の難しさクライアントサーバーアーキテクチャ(Client-Server)
クライアント(ユーザー端末)がリクエストを送り、サーバーが処理して応答する構造。<メリット>中心サーバーでデータや処理を一元管理できる
<デメリット>サーバーに負荷が集中する
②アーキテクチャ特性
特性 | 英語 | 意味 |
---|---|---|
可用性 | Availability | システムが必要なときに継続的に利用できる度合い。ダウンタイムを最小限に抑えることが重要。 |
信頼性 | Reliability | システムが期待通りに動作し続ける能力。長時間の運用でも誤作動や不具合が少ないことを指す。 |
テスト容易性 | Testability | システムやコンポーネントがテストしやすいかどうか。単体テスト・統合テスト・自動化テストのしやすさも含まれる。 |
スケーラビリティ | Scalability | 負荷の増加に対して、システムの能力を拡張できる性質。サーバーの追加やクラウドスケーリングで性能を維持可能。 |
セキュリティ | Security | データや機能を不正アクセスや攻撃から守る能力。認証、認可、暗号化、監査ログなどが含まれる。 |
アジリティ | Agility | 環境や要件の変化に迅速に対応できる柔軟性。新機能追加や改善のスピード感が問われる。 |
耐障害性 | Fault Tolerance | 一部の障害が発生しても、全体としてサービスを継続できる能力。冗長構成やフェイルオーバー設計が重要。 |
弾力性 | Elasticity | 負荷の増減に応じて、必要なリソースを自動で増減できる性質。クラウドネイティブな特徴。 |
回復性 | Recoverability | 障害や停止が起きたときに、どれだけ迅速に元の状態へ戻せるか。MTTR(平均復旧時間)で測定されることが多い。 |
パフォーマンス | Performance | システムの応答速度や処理能力。スループットやレイテンシが主な指標。 |
デプロイ容易性 | Deployability | システムを本番環境に反映する作業がどれだけ容易か。CI/CDパイプライン、自動デプロイが鍵。 |
学習容易性 | Learnability | 開発者や運用者がシステムをどれだけ早く理解し、習熟できるか。ドキュメント整備やコードの可読性も影響する。 |
③アーキテクチャ決定
システムをどのように構築すべきかの ルール を定めるものであり、開発チームが従うべき「設計上のガイドライン」となります。
下図の例にあるように、レイヤードアーキテクチャにおいて以下のような決定が行われるケースがあります。
【ルールの例】
このようなルールによって、各層の責務が明確になり、システムの健全性や実装の一貫性や保守性が高まります。
④設計指針
設計指針(Design Guidelines) は、アーキテクチャ決定と異なり、堅苦しいルールではなく ガイドライン として開発チームに示されるものです。
目的は「すべてのケースを縛ること」ではなく、「望ましいアプローチを推奨すること」です。
- 推奨されるアプローチを示す
→ 非同期メッセージング、CQRS、イベント駆動設計など - 柔軟な選択を可能にする
→ 必ず従うルールではなく、状況に応じた判断を助ける - 開発チームの一貫性を高める
→ 全体の方向性を合わせつつ、現場の裁量を尊重
【例】
指針:「マイクロサービス間では、可能な限り 非同期メッセージング を利用してパフォーマンスを向上させるべき」
指針から、「非同期メッセージングを優先」というガイドラインをチームに与える
2. アーキテクトに期待されること(1.2)
刻々と変化するソフトウェアアーキテクチャの範囲の中で、
アーキテクトは「設計図を描く人」にとどまりません。期待される役割は多岐にわたります。
アーキテクチャ決定を下す
アーキテクトは、技術選択を 指定するのではなくガイドする ことが重要です。 「Reactを使え」と決めるのではなく、「リアクティブWebフレームワークを使う」とガイドすれば、チームはReact/Angular/Vueなどを柔軟に選択可能です。 ただしスケーラビリティや可用性を確保するためには、特定技術の選択が必要になる場合もあります。その線引きを見極める力がアーキテクトに求められます。継続的に分析・改善する
アーキテクトは、システムの 健全性を継続的に分析 し改善策を提案する役割があります。 古いアーキテクチャを放置すると「構造的崩壊」を招き、性能や可用性が劣化します。 また、テスト・リリース環境も分析対象であり、変更が素早く検証・リリースできなければアジリティは失われます。変化に応じて常にアーキテクチャを見直す姿勢が不可欠です。最新のトレンドを把握し続ける
アーキテクトは、開発者以上に 最新の技術や業界動向を追う ことが求められます。 アーキテクチャの決定は長期的影響が大きいため、主要なトレンドを理解していなければ適切な判断ができません。 技術力に加えて「未来を見据えた判断力」を養うために、学習と情報収集を継続することが必要です。決定の順守を徹底する
アーキテクトは、定めたアーキテクチャ決定や設計指針が チームに順守されているかを継続的に確認 する責任があります。 例えば「プレゼンテーション層はDBに直接アクセスしない」というルールを破ると、アーキテクチャ全体の特性(スケーラビリティ、可用性など)が崩壊します。 適応度関数や自動化ツールを活用してルール順守を担保することが推奨されます。さまざまなものに触れ、経験している
アーキテクトには 技術の幅 が求められます。 専門家レベルの深さだけでなく、複数の技術の特徴・長所・短所を理解しておくことが重要です。 異種混合の環境では、幅広い経験があるほど柔軟に対応可能です。1つの技術に固執せず、積極的に学び続ける姿勢がアーキテクトの強みになります。事業ドメインの知識を持つ
アーキテクトは ビジネスドメインの専門知識 を持つ必要があります。 技術だけ知っていても、ビジネス用語やドメイン特有の課題を理解できなければ、ステークホルダーとの信頼関係は築けません。 成功するアーキテクトは、ビジネス側の言葉で会話し、要件を正しく理解した上で最適なアーキテクチャを提案できます。対人スキルを持ち合わせている
アーキテクトには、リーダーシップ・ファシリテーション・チームワーク などの対人スキルが必須です。 優れた技術力があっても、チームを導けなければ有能なアーキテクトとは言えません。 アーキテクトは人を動かす力を磨くことで、他との差別化を図り、チームから信頼される存在になれます。対人スキルや政治的バランスを理解する
アーキテクトは 社内政治や交渉の舵取り も担います。 アーキテクチャ決定は多くの場合、コストや工数、既存システムへの影響から反発を受けます。 そのため、ステークホルダーとの交渉術が不可欠です。開発者時代の「コード設計」よりも広範で重要な判断を行い、その正当性を示すために戦う力が必要となります。技術力だけでなく、ソフトスキルや組織のかじ取り力 が求められる点が強調されています。
3. アーキテクチャと交わる領域(1.3)
アーキテクトの判断は技術の枠を超えて広がります。アーキテクチャは「技術だけで完結しない学際的な活動」であることが示されています。
-
エンジニアリングプラクティス(XP、CI/CD など)
従来、アーキテクチャはウォーターフォールやスクラムといった「プロセス」とは分離されていましたが、継続的インテグレーション(CI)や継続的デリバリー(CD)といった概念が出てきたことで関連せざる負えなくなりました。 -
運用と DevOps(監視、可観測性、デプロイ方法)
監視やログ収集といった 可観測性 は、障害対応やシステムの回復性に不可欠であり、デプロイ戦略(Blue-Green、Canaryなど)も、どのようなアーキテクチャが選べるかに影響します。 -
プロセス(アジャイル、スクラムなどの開発手法)
マイクロサービスをウォーターフォールで開発すると摩擦が大きい。反対に、アジャイル的な反復的プロセスはマイクロサービスに適しているなど、適したプロセスとの組み合わせが重要です。 -
データ(モデリングやガバナンス)
データモデリングの方針を誤ると、どんなに優れたアーキテクチャでも破綻しかねません。
例えば、マイクロサービスでは サービスごとのデータベース分割 が前提となり、データガバナンスや一貫性モデルの工夫が必要になってきます。
4. ソフトウェアアーキテクチャの法則(1.4)
著者らはアーキテクトが前提とすべき基本原則を「アーキテクチャの法則」として紹介しています。
ここで例示されるのは次のような考え方です。これらの思想は本書全体を通じて繰り返し登場します。
【ソフトウェアアーキテクチャの第一法則】
すべての決定にはトレードオフがある
トレードオフがない完璧な選択肢は存在せず、常に利点と欠点のバランスを取る必要があるといっています。
【ソフトウェアアーキテクチャの第二法則】
「どうやって」よりも「なぜ」の方がずっと重要だ
アーキテクトがトレードオフの末に「なぜ」その決断を下したのかに焦点を当てる必要があるといっています。
まとめ
第1章では、「アーキテクチャとは何か」「アーキテクトとはどんな人か」を再定義することが目的でした。ただの定義や肩書き紹介にとどまらず、アーキテクトに期待される思考や振る舞いにも踏み込んでくる重さがあります。
- アーキテクチャは「後から変更しづらい重要な決定の集合」で、単なる構造図よりも、選択と制約の重みを含むものとして捉えられる。
- アーキテクトには技術だけでなく、ガイドする力、説得する力、関係者と協働する力も不可欠。
- 判断の範囲は開発だけに留まらず、プロセス、運用、データ、テスト体制 といった領域にも及ぶ。
- すべてはトレードオフの上に成り立つので、「何を犠牲にし、何を守るか」が問われる。
終わりに
本章で語られたことは一見抽象的に思えるかもしれません。しかし、アーキテクトとして長く働いていくなら、これらの基礎観を体に染み込ませ、毎日の判断に活かしていかねばならないと痛感致しました。
現在自分が従事しているプロジェクトに対して「後から変えにくい決定事項は何か」、「開発チームとして、どこまでアーキテクトのガイドを許容すべきか?」、「今の設計判断に、技術以外(データ、運用、プロセス)の視点は入っているか?」などを改めて問いかけようと思いました。
第1章で示された「判断の枠組み」をベースに、2章以降では具体的なアーキテクチャ思考やスタイルについて掘り下げていきます。