『ソフトウェアアーキテクチャの基礎』読書メモ・感想

年末年始に、そのボリュームの多さになかなか手がつけられていなかった『ソフトウェアアーキテクチャの基礎 -エンジニアリングに基づく体系的アプローチ』を読みましたので、自分なりのまとめと感想を記事にしました。

www.oreilly.co.jp

どんな本?

  • 現代のソフトウェアアーキテクチャのバリエーションやトレンド、それぞれの特徴について解説しつつ、ソフトウェアアーキテクトという職業に求められるスキルなどについても解説している本
  • いわゆるコードレベルの設計ではなく、例えばマイクロサービスとか、モノリシックなアーキテクチャとか、そういう次元の話
  • 自分は本書でいう「アーキテクト」の仕事はしたことはなく、「開発者」の立場として読んだが、興味深かった
  • あまり知らない領域の話だったものの、丁寧に解説されていて、大事なことは何度も繰り返し主張されるので、意外と理解に困ることはなかった

各章の自分的まとめ・感想

2章「アーキテクチャ思考」

  • アーキテクトは、技術的な深さよりも幅が求められ、そのための努力が必要
  • アーキテクチャ決定は必ずトレードオフであることを意識する必要がある

3章「モジュール性」

  • 計算式は理解が難しくて完全にはわからなかった
  • 適切な抽象化やコナーセンスの度合いを抑えることで変更につよいシステムを構築することが必要

qiita.com

4章「アーキテクチャ特性」

  • いわゆる「非機能要件」の言い換え的な話
  • 色々な特性(信頼性、拡張性、etc)があるが、全てを取るのは不可能であり、どの特性が必要かを選択する必要がある
  • 詰まるところ、これもトレードオフの関係になるし、イテレーティブな設計になっていればやり直しがしやすくなる

5章「アーキテクチャ特性を明らかにする」

  • ドメインの関心事をアーキテクチャ特性として翻訳する
    • この際に、短絡的にならないように注意。
    • 例えば、市場投入までの時間というドメインの関心事に対して、「アジリティ」というアーキテクチャ特性だけに翻訳してしまうと、テスト容易性やデプロイ容易性の観点を損ない、目的が達成できない可能性がある
  • アーキテクチャ特性の優先順位を決めすぎず、上位3を決める、というような方法にする
    • どのアーキテクチャ特性が重要ではないかを決めるのは必要だが、一番必要なのはどれか、というところは不毛な議論になりやすい
  • アーキテクチャアーキテクチャ特性を満たさなくても、アプリケーションの設計で満たすことができる可能性もある

6章「アーキテクチャ特性の計測と統制」

  • アーキテクチャ特性を計測する仕組みを作ることが必要
  • また、必要と決めたアーキテクチャ特性については、適応度関数の仕組みなどを入れて統制させる仕組みづくりが必要

7章「アーキテクチャ特性のスコープ」

  • アーキテクチャ特性について、以前はシステム全体に対する特性、だったが、現代の開発では、マイクロサービスの登場などにより、もっと細かい単位でスコープの設定をするべき状況になっている
  • その単位を著者らは「アーキテクチャ量子」と定義している
  • 本章では、オークションサイトのアーキテクチャ例を紹介しながら、例えば入札者と競売人で必要なアーキテクチャ特性が異なることなどを説明している

8章「コンポーネントベース思考」

  • モジュールをパッケージ化した「コンポーネント」を発見することが必要
  • そのためには、アーキテクチャをどのように分割するか(最上位の分割)を決める。
    • これには、ドメインによる分割や、技術による分割などの手法がある

10章「レイヤードアーキテクチャー」

  • シンプルで親しみやすく、コストが低い
  • アーキテクチャが固まっていない時点の出発点としても適切になることが多い
  • 一方で、システム単位が大きくなるので、デプロイ容易性や、弾力性、耐障害性(どこかでメモリ不足になると全体がクラッシュ)が低いなどのデメリットもある

11章「パイプラインアーキテクチャ

  • bashzshの基本原則になっているようなアーキテクチャ
  • 特にシンプルな一方通行の処理を数sめるタスクで用いられる
  • シンプルなのは強みである一方で、基本的にはモノリシックなので、弾力性などは低い

12章「マイクロカーネルアーキテクチャ

13章「サービスベースアーキテクチャ

バランス型、という感じで、書籍の中でも割と推されているような記述ぶりに感じた。

14章「イベント駆動アーキテクチャ

  • 非同期的にイベントを送受信して処理するアーキテクチャ
  • リクエストベースモデルとイベントベースモデルという分類がある
  • ブローカートポロジーは、イベントの処理が終わったのち、受信する人がいるかどうかを気にせずイベントを発生するもの。拡張性に優れるが、ワークフローを管理する役割を持つ機能が不在
  • メディエータートポロジーは、イベントの受信を請け負って、ワークフロー全体の動向を管理するが、その分拡張性はブローカーほどではない
  • 他のアーキテクチャとハイブリッド形式で採用されることも多い

15章「スペースベースアーキテクチャ

  • キャッシュを使った(DBへの接続回数を減らす)アーキテクチャ
    • 複数の「処理ユニット」間で、データのキャッシュをレプリケーションして同期的に持つ(ただし、レプリケーションではなく、一元的にキャッシュを管理して各処理ユニットがリモートアクセスする分散キャッシュを利用することもある)
    • キャッシュを更新してからDBを非同期で更新する
  • それゆえ、更新のタイミングによってはキャッシュのデータに不整合が生じることもある
  • クラウドとオンプレミス環境を跨いでデプロイする(例: DBと読み書きをするデータリーダー/ライターだけオンプレにする)こともできる
  • これらの特徴から、コンサートチケットのサイトなどに適している(DBへのアクセスが少なく、弾力性が高い)
  • 一方で、非常に複雑なので、テストが難しく、コストも高くなる

16章「オーケストレーション駆動サービス指向アーキテクチャ

  • 過去に分散アーキテクチャとして考案されたものの、あまりうまくいかなかったもの
  • 再利用することに対するトレードオフは結合が高まること

この章の話は、全体的にあまりピンと来なかった

17章「マイクロサービスアーキテクチャ

  • 高度な分離をし、「境界づけられたコンテキスト」の論理的概念を物理的にモデル化することを目的としたアーキテクチャ
  • 「マイクロ」という名前は最小のという意味より、単なるラベル名と思うべき。トランザクションがサービス間を跨ぐことがないようなものであることは必要。
  • データベース含めて高度に分離されるので、各サービスで言語環境を変えるなどの組織計画も可能になる
  • サービス間で連携が必要な場合は、イベント駆動アーキテクチャでいう「ブローカー」や「メディエーター」のパターンを採用する
    • それぞれのメリット・デメリットはブローカー/メディエーターと同じ
  • どうしてもサービスを跨いでトランザクションを構築したい場合は、サーガという「メディエーター」の役割をするサービスを別途構築してそのサービスに管理させるという方法があるものの、結合してしまうトレードオフがあるので、基本的にはサービスを跨いでトランザクションを構築するのは推奨されず、サービスの粒度の見直しを優先的に検討するべき
  • コストや複雑性は課題だが、現在のエンジニアリングプラクティスで重視されるデプロイやテストの容易性に強みを持つ

19章「アーキテクチャ決定」

20章「アーキテクチャ上のリスクを分析する」

  • リスクマトリックスを利用し、アーキテクチャ内のどの部分にどのようなリスクがどのくらいあるかを分析する
  • リスクアセスメントとしてドメイン領域などで区切ってレポートにまとめる
    • この際、リスクの方向(改善か、悪化か)も重要な情報となる。リスクの方向の伝え方は工夫が必要(矢印などだと誤解を生みやすい)
  • 開発者(テックリード)と一緒にリスクストリーミングを行い、
    • リスクの特定(これは個人作業)
    • リスクの合意(どのアーキテクチャにどのレベルのリスクがあるかの合意を取る)
    • リスクの軽減(最も重要。合意したリスクに対して、それを軽減する方法を検討する。これを丁寧に行うことで、コスト増とのトレードオフ調整などがしやすくなる側面もある)

21章「アーキテクチャの図解やプレゼンテーション」

  • アーキテクトは良いアーキテクチャを考えても、きちんと伝えなければ意味がない
  • 図解を作成する上では、時間をかけすぎると作成した資料に執着が生まれてしまい、検討の邪魔になるので、最初は付箋などアナログな方法を活用してイテレーティブにできると良い
  • 図解を示したり、プレゼンテーションを工夫しないといけない

具体的な方法がいくつか述べられていた。今は生成AIを活用するのもよさそうと思った。

22章「効果的なチームにする」

  • アーキテクトが作成する制約はキツすぎても(コントロールフリーク)、緩すぎても(アームチェアアーキテクト)いけない
    • 開発者からアーキテクトになりたてだと、コントロールフリークに陥りやすい
    • 逆に、開発から離れていると、アームチェアアーキテクトに陥りやすい
  • どのように管理するのが良いかは、チームやプロジェクトの性質によるので、都度分析が必要
  • プロジェクトメンバーが多すぎると、多元的無知(自分の意見が言えなくなる)、責任の分散(自分で何かしようと思わなくなる)など、不具合が発生しやすくなる
  • チェックリストを活用する。静的解析など自動化できるものは自動化する
  • 開発者が技術スタックを使用したいときには、「ビジネス上の根拠」も確認するようにする
    • 開発者は、これが達成できないのに使用をしたいということがある

マネージャーとアーキテクトの棲み分けもなかなか難しそうと思った。
また、これを見るとアーキテクトは設計して終わりではなくて、開発・運用する間も一緒にプロジェクトを走らないと意味ないんだなーという感想を持った。

23章「交渉とリーダーシップのスキル」

  • 交渉
    • アーキテクトが下すほぼ全ての決定には異議が唱えられるため、交渉の力が非常に重要
    • ステークホルダーとの普段の会話から重要なアーキテクチャ特性を見極め、交渉の要素にすると良い
    • 交渉の際には、費用は時間は非常に重要であるものの、交渉の材料としては最後の手段にするべき
    • ステークホルダーが譲れないと言っている条件が、実はシステム全体ではなくシステムの一部が対象であり、その結果コストを抑えられることもある
    • 他のアーキテクトと衝突した場合は、議論しすぎるのではなく、冷静に実証することに努める
    • 相手が聞くのをやめてしまわないよう、根拠や理由を最初に説明する
  • リーダシップ
    • アーキテクトという肩書きで仕事をするのではなく、手本を示して周りを動かす
    • 開発者が質問や問題を相談できる相手になることを心がける
    • 開発チームに溶け込む時間を確保するため、アーキテクトは招待されたMTGについては自分の必要性を確認しつつ、開発者がMTGに巻き込まれているのを見たら、自分が代わりに参加して開発者の時間を確保することを検討する

交渉の方は、本で読むだけでしんどい仕事だなー、、、と感じた。
バズワードを利用する」というのは一般的には反感を買いそうな言葉だなーと思ったが、交渉のテクニックとしては必要か、、という気持ち。
リーダシップの方は、アーキテクトに関わらずリーダの役割として仕事をする上で大切なことが書かれている気がした。
「肩書きで仕事しない」の箇所は、「役職で仕事をしないこと」と公務員をしていた頃に散々聞いてきた話を久々に聞いた感じがして懐かしい気持ちになった。

第24章「キャリアパスを開く」

  • 技術は目まぐるしく変化するので、常に学び続ける必要がある
  • 朝一、20分の時間を使って技術的な幅を広げるための時間を作る(「未知の未知」を「既知の未知」にする)
  • テクノロジーレーダーを活用して、自分が次に何を追求するかのビジョンを描く
  • ソーシャルメディアを使用して、「弱いつながり」(新しい仕事のオファーや普段の経験の外側からのアドバイスが期待できる)を広げる

みんな分かっているけどなかなかできないよね、、という章。
ただ、20分を使って、「未知の未知」を「既知の未知」にする、というのはハードルが下がってよさそうな気がした。
あとSNSは、どうしても自分には向いていないと思ってしまうので、どうしたもんかな、、、という感想でした。