Rのつく財団入り口

ITエンジニア関連の様々な話題を書いているはずのブログです。

【感想】『ソフトウェアアーキテクチャの基礎』:モダンなアーキテクティングの体系的な教科書

すべてはトレードオフである!(ばばばばーん)

 2022年3月刊行、ITエンジニア本大賞2023にもノミネートされた良著と名高い一冊。今回も翻訳は島田浩二さんです。
 ソフトウェアアーキテクトやテックリードに(たぶん)近い位置にいる身としてもこれはいつか読まねば!と思っていたのですが、オライリーの2023年カレンダーと一緒に物理本で買ってきてじっくり読みました。以下、各章ごとに読書記録や感想など。

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

www.oreilly.co.jp

1章 イントロダクション

 序文で「公理を疑え」、過去の時代の前提も疑ってかかるのがアーキテクトの仕事だ、今の時代は「変化」への対応こそが設計上の重要事項だ...と述べつつ、アーキテクチャを巡る旅が始まります。

  • アーキテクチャとはそれが何であれ重要なものだ、という引用がある。かつては一度実装すると変更が難しいもの、という定義もあったが時代遅れに。
  • マイクロサービス、DevOps、クラウド、コンテナ、アジャイル、歴史上現れた様座な要素と共に変わっていく。文脈の中で初めて理解できるもの。
  • ソフトウェアアーキテクチャを構成するものは...
    • システムの構造:アーキテクチャスタイルの種類。レイヤードやマイクロサービスなど。
    • アーキテクチャ特性:後述の様々なイリティ(-lity)。
    • アーキテクチャ決定:どのように構築するかのルール。レイヤーをまたぐ際のアクセス制限など。
    • 設計指針:ルールではなくガイドライン。非同期メッセージングをなるべく使おうなど。
  • アーキテクトへの期待とは...
    • アーキテクチャ決定を下す人である。ガイドであるべき。例えば特定のFWを指示するのでなく選択させるなど。
    • アーキテクチャを継続的に分析する人。時が経つと変わる。
    • 最新のトレンドを把握し続ける人。技術や業界動向にアンテナを張る。
    • 決定の順守を徹底する人。開発チームにルールをまもってもらう。
    • さまざまなものに触れ経験している人。技術、FW,プラットフォーム、環境。深さより幅。
    • 事業ドメインの知識を持っている人。一定の知識はいる。
    • 対人スキルを持っている人。チームワーク、リーダーシップ、ファシリテーション
    • 政治を理解し、舵取りをする人。チームの外部との交渉役。
  • この10年でクラウドの普及で弾力性も高められるようになったり、DevOpsが出てきたり、歴史と共に変化が大きい。今日では進化的なアーキテクチャが求められている。
  • ソフトウエア開発のプロセスとエンジニアリングプロセスは分けて考えた方がよい。
  • ソフトウェアアーキテクチャの第一法則:トレードオフがすべてだ。
  • ソフトウェアアーキテクチャの第二法則:「どうやって」よりも「なぜ」が重要である。

どどーんと出てくる第一法則にやっぱりこれなのか~!と思いつつ、順に詳細に踏み込んでいきます。他の章もそうですが過去の歴史上の経緯の話なんかもあちこちに出てきて、このへんも参考になりますね。

第I部 基礎

2章 アーキテクチャ思考

 アーキテクトらしく考え、物事をアーキテクチャの観点で見ていくアーキテクチャ思考の章。

  • 色々あるアーキテクチャ特性を検討し、アーキテクチャスタイルからどれかを選択。コンポーネント構造を考えるのがアーキテクトの仕事。これをもとにクラス設計、UI、ソースコードを書いていくのが開発者の仕事。と両者を分断するのが従来の責務モデルだった。今日ではこの境界はなく、両者を行き来しながらコラボレーションするのが正しい形。
  • 知識のピラミッドは上から「わかっていること」「わかっていないとわかっていること」「わかっていないとわかっていないこと」の3層に分けられる。開発者は頂点の「わかっていること」を維持し伸ばしていくのが技術的な深さになり重要。しかしアーキテクトは技術の深さよりも幅を広げ、「わかっていないとわかっていること」を広げるほうが重要である。
  • アーキテクチャとは、Googleで答えを見つけられないもの。絶対的な正解はどこにもない。すべてがトレードオフである。
  • アーキテクトになってもコードを書き、技術的な深さは維持できているべきである。フルタイムの開発者ではないのでボトルネックにならないよう注意。小さな機能を実装する、概念実証を頻繁に行う、優先度が低いストーリーやバグ修正を受け持つ、自動化の支援やツール作りを担当するなど。

 この「知識のピラミッド」の図はよく可視化されていて、なるほど...となりました。アーキテクティングとコーディングのバランスをどう取るかの話で、アーキテクトになってもコードを書くべきだ!という主張には作者さんたちの固い信念を感じます。

3章 モジュール性

重要だけど定義があいまいなモジュールについての章。

  • 「より複雑な構造を構築するために使用できる標準化された部品または独立した単位の各集合」が一般的な定義。
  • 主要な言語はそれぞれ仕組みを持っている。Javaのパッケージ、C#PHP/Ruby/Python名前空間など。かつては構造化プログラミングが注目された頃、モジュラー型言語が生まれた名残。
  • モジュール性には凝縮度、結合度、抽象と実装の比率からなる抽象度、結合度から導かれる変更された時に壊れやすいかを表す不安定度、計算から求める主系列からの距離がある。
  • 後に、あるコンポーネントを変更した際に別のコンポーネントも変更が必要な状態を表す「コナーセンス」という言葉がある。
  • コナーセンスの種類に 名前/型/意味/アルゴリズム/位置/実行順序/タイミング/値/アイデンティティ があり、左に行くほど結合の度合いが下がって望ましい。こちらに方向にリファクタリングする。

 なかなか難しい数式が出てくるのですが、学術的にはいろいろ調査されているのが分かります。

4章 アーキテクチャ特性

  • 非機能要件と呼ぶ場合もあるが、ネガティブな印象があるので本書では「アーキテクチャ特性」という言葉を使用。ドメインに関係しない設計の考慮事項、設計の構造的な側面に影響を与えるもの、アプリケーションの成功に重要なものである。
  • 運用特性、構造特性、横断的特性の3つのカテゴリーがあり、その中に様々な特性がある。「イリティ(-ility)」と呼ぶ
  • 結局はトレードオフなので、すべてを満たす最善で汎用的なアーキテクチャを狙わない。少なくとも最悪の選択をしないようにする。

 アーキテクチャ特性周りや用語は様々な会社で独自の言葉で定義したりして混乱を招いている...というコラムがあります。僕の会社でも探すと確かにこのへんいろいろ資料があるのですが、独自定義けっこうありそうです。

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

  • ドメインの関心事や要件からアーキテクチャ特性を導いていく実例。
  • 例題を使って個人練習していくアーキテクチャ・カタというやり方がある。
  • 実際のカタとして、サンドイッチ販売をオンライン展開しようとしている「シリコン・サンドイッチ」での例。
  • アーキテクチャ選択に不正解はあるが正解はない。あるいは、間違った答えはなく高くつくものだけがある。

 コラムでこのトレードオフ分析が大事、また開発に関わる面々と一緒に協力しあうのも重要とあり、怠ると「象牙の塔のアーキテクトアンチパターン」に繋がるとのこと...確かに実際の開発に関わらないエライ人の小難しい机上の空論ではダメなわけですね。

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

  • 特性は形が定まっていなかったり、組織内で定義が様々だったり、複合的で計測しにくかったりする。
  • 運用面では客観的尺度として、コードから得られる「循環的複雑度」がある。統制についてはコードの「適応度関数」を求める手法があり、JUnitから触発されたArchUnitがある。

qiita.com

 循環的複雑度は「サイクロマティック複雑度」ともいい、むかーしEclipseかなんかで自分も試した記憶があります。VSCodeC#用の拡張機能で作ったという方もおられますね。

qiita.com

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

  • コナーセンスを元に、本書ではアーキテクチャ量子」という言葉を定義。独立してデプロイ可能か、機能的な凝縮性を持っているか、同期的なコナーセンスがあるか、からなる。
  • オンラインオークション会社のカタを元に解析した実例。

 難しい話なのですが本書II部の各アーキテクチャスタイルでもこのアーキテクチャ量子は数字で掲載され、モノリスなら1、マイクロサービスなら1以上~という感じになっています。アーキテクチャ図の大まかな四角の数みたいな感じでしょうか。

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

  • 関連するコードの集まりが「モジュール」。モジュールが集まって物理的にパッケージ化されたものを「コンポーネント」。Javaのjarファイル、.NETの.dllファイル、RubyのGemなど。
  • 関連するモジュールをひとまとまりにしたモジュールは「ライブラリ」と呼ばれることが多い。他にもサブシステムだったり独立してデプロイ可能だったりマイクロサービスのような分散サービスを提供するものもみな「コンポーネント」。
  • 特にマイクロサービスは、1つのサービスの中に複数のコンポーネントがある場合もあれば、規模が小さくてサービス≒コンポーネントとなる場合もある。
  • ソフトウェアアーキテクトが関わる設計構造で最小単位がコンポーネントだが、ふつうコンポーネント設計の細部は開発メンバーに任せる。
  • 最上位の分割が2つあって...

    • 技術による分割:技術的関心事の分離。プレゼンテーション層/ビジネスルール層/サービス層...のようなレイヤードアーキテクチャの基本パターン。コードの分類で明確に分離できる。逆にグローバルなレベルでの結合度は高くなり、データレベルの結合度が高くなる。
    • ドメインによる分割ドメイン駆動設計と関連。ビジネス的な機能に近い形でモデル化、分割。マイクロサービスを始め、モノリシックでも近年採用が増えている。同じ特定処理を行うコードが複数ドメインに出てきたりする。
  • コンウェイの法則」:システムを設計する組織は、そのコミュニケーション構造をそっくり真似た構造の設計を生み出してしまう。

  • 「逆コンウェイ戦略」:望ましいアーキテクチャ推進のためにチームと組織構造を共に発展させる。ドメインによる分割なら、ドメインごとに職能横断チームを編成すればよい。
  • コンポーネントの初期設計では、DBのエンティティ(物理的なテーブル)ひとつひとつをひとつひとつのコンポーネントとして設計してしまう「エンティティの罠」アンチパターンに注意。
  • データテーブルのテーブルを示すと定義された関係に基づいてUIを作ってくれるシンプルなCRUDアプリ用フレームワークNaked Objects が昔あった。その後.NET版のNaked ObjectsJava版はApache Isisに受け継がれた。Ruby on Railsを始めとするFW群のスキャフォールディング機能もこの系譜。 DBからUIに単純にマッピングするだけならアーキテクチャは不要で、これらのフレームワークで十分である。
  • 最上位の分割と同様基本的な決定に、モノシリックアーキテクチャか分散アーキテクチャ化の決定がある。ここでアーキテクチャ量子が役立つ。

 調べたところこのNaked Objectsが話題になったのは2000年代後半でした。その後Java版のApache Isisがリリースされたのが2013年、この頃はもうJava全盛期は終わっておりあまり話題にならなかった感じですね。
 Railsがスキャフォールディング機能を使って少ないコマンド操作で爆速でアプリが作れる!と話題になったのが20000年代後半から。そのあたりの歴史的背景にも触れているのがありがたいです。

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

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

  • アーキテクチャスタイル:フロントエンドやバックエンドのコードがどう編成されているか、データストアとどう相互作用するかの包括的な構造
  • アーキテクチャパターンアーキテクチャスタイルの中で特定の解決策を作るのに役立つ低レベルの設計構造

と、本書ではスタイルの中にパターンを含む意味づけですが、スタイル≒パターンで同じ意味で使われることも多い...として、いくつかのアーキテクチャスタイルを星取表のようなアーキテクチャ特性の評価、使いどころなどを述べながら論じていきます。本書の中核ですね。第I部の途中が難しく感じた方でも、この第II部は図を元に読み解いていけば復活できるかと思います。

9章 基礎

  • 巨大な泥団子(Big Ball of Mud): アーキテクチャ構造不在の行き当たりばったりなダメなアンチパターン
  • ユニタリー(一元的)アーキテクチャ:ハードとソフトが1対1の、ソフトウェアが誕生した頃の昔の構造。
  • クライアント/サーバー2層アーキテクチャとも。フロントとバックで分離。昔はデスクトップ上のアプリ+別の場所のDBサーバー。その後ブラウザ+別の場所Webサーバーとなり、これも2層アーキテクチャと呼ばれる。199年代後半になるとフロント+アプリケーション層+データベース層の3層アーキテクチャが流行。
  • 単一のデプロイされるアプリで完結するモノリシックアーキテクチャと、ネットワーク上に分散する分散アーキテクチャの2種類に分類できる。
  • 分散アーキテクチャは強力で今日はよく使われるが、ネットワークを常に信頼したり安全と思いがち、レイテンシーを無視しがち...など8つの誤信があるのに注意。

8つの誤信の形は具体的で、確かにこのへん信じがちだなあと思います。
 コラムではかつてJava言語の設計者はすべてが3層アーキテクチャになることを見込んで、Javaオブジェクトをネットワーク上も移動できるようにしたSerializationの仕組みを組み込んで今日でも残っているが、もう無駄になっている...という話は時代の変遷を感じます。「設計はシンプルに」はいつでも大事ですね。

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

  • プレゼンテーション層ービジネス層ー永続化層ーデータベース層と技術によって分離したアーキテクチャ。層はN個でもっと増えたり、物理的に何処かの層を外出しにしたりバリエーションがある。
  • 共有部品などを配置したサービス層を閉鎖でなく開放レイヤーとして配置する手がある。
  • 気をつけないと不要なレイヤー間の移動がメモリとパフォーマンスに悪影響するだけになってしまうアンチパターンは「アーキテクチャシンクホール」と呼ばれる。

 よく見る、僕も仕事でよく使ってきたレイヤードアーキでした。層をうまく分離していれば、例えばJavaJSF(ゼロ年代Strutsの後に流行ると言われて結局流行らなかったWebフレームワーク)で作っていた画面を後からReactに変えたりもできる...と書いてあったりして、さすが2020年代の本だなと時代を感じます。

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

  • 完全に自己完結で他のフィルターから独立した「フィルター」とフィルター間を通信チャネルで結ぶ「パイプ」からなるアーキ。Unixシェルを|で結ぶ例が有名。
  • 分散メッセージングシステムの Apache Kafka がこのアーキの代表例で、データ処理を各フィルタで行っている。

 Unixコマンドを習い始めた頃におおーと思ったあれでした。コストやシンプルさでは高い評価の一方、弾力性やスケーラビリティが最低評価なあたりが、まだクラウドがなかった20世紀に生まれた考え方だなあと思います。

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

カーネル」と聞くとUnix/LinuxのOSのカーネルなんかをつい連想して難しそうですが、そんなことはありませんでした。Webアプリケーションではあまり見ないアーキテクチャですが、変更容易性を保ったまま機能をうまく制御できそうです。

 ここまでがモノリシックアーキテクチャ、ここから先が分散アーキテクチャです。

 なおこの分野の書籍としてこちらも日本のエンジニア界でも話題になったUncle Bobの『Clean Architecture』。この本もボブおぢさんの主張が強くて面白いのですが、この本の最後のほうで紹介されている「The Clean Architecture」、その前身となる「オニオンアーキテクチャ」は本書には登場せず。

iwasiman.hatenablog.com

まあクリーンアーキテクチャは明確なアーキテクチャというよりはコンセプト的なものなので他と抽象度が違ったのかなと思います。このあたりは、こちらも面白い書籍『ちょうぜつソフトウェア設計入門』にも詳しいです。

「The Clean Architecture」自体はモノリシックか分散かでいえばモノリシックアーキテクチャ。レイヤードアーキテクチャを変化させて進化させたような形でしょうか。
『Clean Architecture』という本の中だとアーキテクチャ「パターン」という呼ばれ方をしています。本書『ソフトウェアアーキテクチャの基礎』の分類方法ではアーキテクチャ「パターン」よりはアーキテクチャ「スタイル」の範疇に入るひとつですかね...このへんやっぱり明確な切り分けはないようです。

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

  • 単一もしくは複数のユーザインターフェース、粒度の粗いアプリケーションの一部(ドメインサービスと呼ばれる)が複数、そしてその先に単一のデータベースがあるアーキ。マイクロサービスやイベント駆動アーキのハイブリッドであり、より複雑さが低い。
  • ドメインサービスはだいたい4個〜12個ほどで規模は大きめ、そして互いに通信はしない。
  • データベースがひとつなのでトランザクションが使え、結果整合性でなく従来のACID属性が保てる。ひとつのデータベースの中を論理的に分ける(スキーマなど)ことで、各ドメインサービスごとに独立性を高める工夫がある。
  • データベースを一部複数にしたり、ドメインサービスの前に全体でひとつのAPIレイヤーを置いたりするバリエーションがある。

 実例の詳しい解説もあり参考になります。読めば読むほど、やらなくても良いのに無理してマイクロサービスに分割して苦労するより、こちらのサービスベーアーキのほうが使い勝手が良さそうという気がします。

 なお書籍『モノリスからマイクロサービスへ』などにも登場する、将来的なマイクロサービス分割に備えたやり方として「モジュラーモノリス(Moduler Monolith)があります。本書でもアーキテクチャスタイル一覧には出てこないのですが8章で言及されています。似ていて微妙に違うのですが、違うのは以下になるようだと理解しました。

  • 「モジュラーモノリス」はコードベースをパッケージや名前空間などでモジュールごとに綺麗に分けて論理的には分割されているが、物理的なデプロイの単位としては全体で一つ。「サービスベース~」は個々のサービスは個別にデプロイ可能。
  • 「モジュラーモノリス」はモジュール同士がやり取りする時はマイクロサービスと違って通信以外にも選択肢がある。ふつうに関数ベースなど。「サービスベース~」はサービスは互いには通信しない模様。
  • 両方とも、データベースは全体で共有もしくは中をスキーマで分けるなどで、ここは同じ。

 サービスベースアーキテクチャの派生形スタイルとでも考えればよさそうです。

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

  • リクエストベースと対になるイベントベース、何らかのイベント発生でアクションが実施されて処理されていく分散非同期型のアーキ。スケーラブルで高パフォーマンス。以下の2つの形態(トポロジー)がある。
  • ブローカー:中央の「イベントメディエーター」がなく、イベントが開始されるとイベントチャンネルを経由して各「イベントプロセッサー」に順々に飛んでいき各自で処理。
  • メディエーター:イベントが開始されるとまず中央で全体を制御する「イベントメディエーター」に飛んでいき、そこから各「イベントプロセッサー」へ。上記のブローカーパターンの欠点を解消した。
  • 非同期なので、例えばWebアプリケーションで処理開始ボタンを押してレスポンスが返ってくるのが速い。
  • エラーの問題を解決するため、エラーが起こったら「ワークフロープロセッサー」に委譲する工夫がある。
  • 全体のアーキで採用されたり、他のアーキをベースにした構造の一部に使われたりと、ハイブリッドな使い方ができる。

 クラウドの例だとAWSAmazon SQSがまさにこれですね。この14章は図や実例がかなり詳しく書いてあります。

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

  • 一般的なWebサーバー/アプリケーションサーバー/データベースの3層だとスケーリングに限界があるところ、スケーラビリティ、弾力性、同時実効性に秀でたアーキテクチャ
  • 「仮想ミドルウェア」が全体を制御。その中に以下4つ。
    • メッセージンググリッド:リクエストを受け取って「処理ユニット」に伝達
    • データグリッド:データを各処理ユニット内にのインメモリDBにレプリケートする。100ms程度で同期。
    • 処理グリッド:処理ユニットを複数呼ぶ際に制御
    • デプロイメントマネージャー:処理ユニットを起動したり停止したり。
  • その先に幾つもの「処理ユニット」があってその中のコンポーネントが処理。各処理ユニット内にインメモリのDBを持ち、互いにレプリケーションする。
  • 処理ユニットでの処理の結果メッセージングで実装された「データポンプ」が送っていき、「データライター」が実際のDBに書き込む。逆に「データリーダー」が読み込む。
  • キャッシュを使うのでデータ衝突の可能性はある。
  • 基本はクラウド上で構築し、データリーダー/リーダーとDBだけをオンプレに配置することもできる。
  • 処理ユニット内のインメモリDBが更新されたらそこで他の処理ユニットにも更新していく「レプリケーションキャッシュ」、別に「キャッシングサーバー」を一つ用意する「分散キャッシュ」の手法がある。

 弾力性を活かしてユーザー数が急増する要件に活用する例として、コンサートチケットの販売、オンラインのオークションシステムが載っており、あっこれAWS認定の設問でよく出るシチュエーションだ!と思い当たったりしました。
 現実的にはほぼクラウド上で実現するのでしょうが、「スペースベースアーキテクチャ」という名前がちゃんとあったのですね。

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

  • 20世紀のマシンがまだ効果だったころ、とにかく再利用を徹底、技術による分割のアイデアを進めたもの。もはや時代遅れとなっている。
  • 最上位に「ビジネスサービス」群、中央に各種機能の「エンタープライズサービス」群があり、再利用なしの「アプリケーションサービス」、「インフラストラクチャサービス」もある。
    全体の核となる「オーケストレーションエンジン」によってリクエストが処理され、メッセージングで経由して各サービスが呼ばれていく。
  • 再利用を主眼に置いたが、あるサービスを修正すると他のサービスにも影響が甚大で実際には利用に耐えなかった。
  • 技術による分割は限界があること、分散トランザクションは難しいという知見を後世に伝える結果になった...

 章タイトルは「オーケストレーション駆動サービス指向アーキテクチャ」なのですが文中では「サービス指向アーキテクチャ」の言葉が普通に使われており、イコールなのかな? 含まれる形なのかな?というがちょっと分かりませんでした。
 ワタクシが2000年代にJavaエンジニアとして活動していた頃に流行ると言われて難しい図が紹介されていて結局廃れてしまったService Oriented Architecture、マイクロサービスの祖先になったともいわれているやつですね。時代が移り変わり新しい要素が出てきて、その結果無用になってしまったこうした過去のアーキテクチャも紹介されているのはありがたいです。

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

  • 2014年のブログ記事を機に広がった考え方。DDDの「境界付けられたコンテキスト(Bounded Context)」の考え方を物理的にモデル化。
  • 再利用を突き詰めるとどうしても悪しき「結合」が発生してしまうので、各サービスで「複製」して使うことを優先、高度な分離を最優先した。技術ではなくドメインによって分割する。
  • 分散アーキテクチャであり、同じマシン上に間借りする時の問題を解決。逆にネットワーク呼び出しなのでパフォーマンスは悪化する。
  • マーチン・ファウラー氏いわく「マイクロサービスという言葉はラベルであり、説明ではない」。名前は「マイクロ」だが粒度は小さいとは限らない。
  • データ分離の要件があり、単一のデータベースでなく各サービスごとに別々に持つ形。
  • 障害時のサーキットブレイカー、ロギング、モニタリングなど各サービスで共通で必ず使うものはコンポーネント化して共通化する「サイドカーパターン」がある。サービスメッシュ、サービスディスカバリー
  • フロントエンドのUIは共通だが、これをUIコンポーネントごとに分割、→対応した各APIレイヤー→対応した各マイクロサービス...と繋がっていく「マイクロフロントエンド」という派生した考え方もある。
  • 複数のマイクロサービスが必要な機能では、各サービスが順に他のサービスを呼んでいく場合もあれば、手前にDBを持たず他のサービスを呼ぶだけの専門の「メディエーター」サービスを配置するパターンもある。
  • サービス境界を跨った分散トランザクションはしないのが最良。代わりに粒度を見直す。必要な場合に人気があるのは「サーガ」パターンで、トランザクションが失敗したら失敗したから巻き戻してくださいメッセージを呼び出し元サービスに送り返す。

「マイクロフロントエンド」はオライリー本でも1つ出ていますね。

分散トランザクションのサーガパターンについては、『マイクロサービスパターン』というかなりがっつりした本で詳しく述べられています。

iwasiman.hatenablog.com

 難しい本で僕も時間をかけて読んだのですが、読めば読むほど、エッここまで複雑にして大変な思いして分散トランザクションてやらなきゃいけないの...?という感想を持ちました。(笑)
 本書では分散トランザクションはやめようとはっきり書いてあって、ああやっぱりそうなんだなとチョット安心しました。"マイクロ"のワードに惑わされがちですが、実際にはマイクロサービスの個数は数個程度で収まるシステムもあるのでしょうね。

18章 適切なアーキテクチャスタイルを選ぶ

 アーキテクチャスタイル群は一通り説明し終わり、どう選んでいくかの章。

  • 過去を観察することで分かることも。エコシステムの変遷で変わることもある。コンテナ技術のような新しい能力でアーキが変わることも。変化の速度も上がりつつある。仕事で携わるドメインの変化、技術の変化、ライセンスが高額のため乗り換えなどの外部要因もある。これらのトレンドから判断していく。
  • 判断基準はドメインアーキテクチャ特性、データのアーキテクチャ、組織の要因、プロセスとチームと運用。特定の問題領域に携わる仕事では、特定のアーキが向いていたり向いていなかったりもある。
  • モノリシックか分散アーキテクチャかの選択。
  • 分散アーキなら、データをどこに置くか。
  • サービス間の通信は課題が少ない同期通信をまず選び、パフォーマンスとスケーリングで必要な場合に非同期通信を選ぶ。

 実際に選んでみた例も解説されています。

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

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

 ソフトウェアアーキテクトとして活動してくための、割とヒューマンスキル寄りの事柄を語った第3部。こちらも名著の『Design It!』と同じようなことも語られており、仕事全般に役立つお話となっています。

19章 アーキテクチャ決定

  • そもそもアンチパターンとは、始めた時は良いアイデアに見えるが後でトラブルに繋がるもの、とのこと。
    • 資産防御アンチパターン:アーキ決定を先延ばしにしてしまう。決定を最終責任時点まで延期すること、開発チームへ継続的に協力することで回避。
    • グランドホッグデーアンチパターン:アーキ決定時に根拠を示さなかったために、後で何度も同じ議論になってしまう現象。2/2の行事の名前で、ビル・マーレイの映画に由来。
    • メール駆動アーキテクチャアンチパターン:アーキ決定をメールで連絡すると皆読まなかったり後で忘れたりする。きちんとドキュメントで周知する。必要な人だけに伝えるとよい。
  • アーキテクチャ上必要なものとして、構造、非機能特性、依存性、インターフェース、構築手法がある。
  • 決定の文書化で効果的なものが「アーキテクチャデシジョンレコード」(ADR)がある。タイトル、ステータス、コンテキスト、決定、影響、コンプライアンス(決定遵守をどうチェックするかなど)を書いていく。

このADRというフォーマットは書籍『Design It!』でも後半で紹介されています。日本ではあまり聞かない気がしますが(表に出てこないだけ?) アメリカでは一般的なのでしょうか。

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

  • リスクの全体的な影響が1-3、発生の可能性1-3でマトリクスを作り、点数が1-9になる。
  • これを元に、各ドメインごとにスケーラビリティ/可用性/パフォーマンス/セキュリティ/データ完全性 毎に点数を振り、表にしてリスク合計を算出。高リスクの所に対応していく。
  • 各分野に詳しい人を呼んでリスクストーミングをするとよい。

 最後にありそうなシステムを元に実例が載っていて、RDBを分割して片方が止まってももう片方の機能に影響がないように、そしてRESTで通信していたところを一部だけキュー形式に...というリスク軽減がなされています。これは分かりやすいですね。

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

人に説明する時のことを扱った何気にお役立ちの章です。

  • アーキテクチャの各部分の関係性を示した「表現の一貫性」を大事に。
  • すごいツールを使って時間を書けて作ってしまうと「アーティファクトへの不合理な愛着アンチパターン」に陥って変えたくなくなるので注意。
  • クラス図「/シーケンス図以外は使われなくなったUML以外にC4という図解手法、ArchiMateというモデリング言語がある。
  • タイトル/線/図形/ラベル/色分けのでの工夫。線だけは標準があって、実践が同期通信、点線が非同期通信。凡例をつけるのも大事。
  • プレゼンではトランジションやanimationで時間の経過を表現したり、長い話はページごとに段階的に図を表現したり。
  • 伝えたい情報は半分は書いて半分は話す。空のスライドというのも注意を引きやすい。

点線が非同期通信というのは、確かに言われてみると書籍に出てくるアーキテクチャ図はそうなっていることが多いような...! ArchiMateというものは日本ですとあまり聞かない気がしますが、どれぐらい使われているのでしょうね。

www.archimatetool.com

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

  • 開発者がアーキテクチャを作っていく上での制約の「箱」をうまく作っていくのがソフトウェアアーキテクトの役割。
  • 3つのパーソナリティあらゆることを細かく決めすぎて厳しく取り締まる「コントロールフリーク」では人が離れてしまう。逆にコーディングもできずチームの近くにもおらずに大雑把な図しか描けない「アームチェアアーキテクト」でもまずい。適切な制約と境界を作り、チームの目標達成を助ける「効果的なアーキテクト」でいよう。
  • チームメンバがどれだけお互いに親しいか、チームサイズが4人以下~12人以上のどのサイズか、メンバの経験の度合い、プロジェクトの複雑さ、期間によってパーソナリティの振る舞いを変えると良い。
  • 人が増えると生産性が下がっていく「プロセスロス」、多数意見に同調してしまう「多元的無知」、人が多すぎると起こる「責任の分散」に注意。
  • コード完成やテストにおけるチェックリストを活用するとよい。
  • ライブラリなどの技術スタックを使うという申し出には、まず既存機能との重複があるか、どんな根拠に基づいての提案かに答えてもらうとよい。
  • システム全体に影響するフレームワークはアーキテクトが決定する。全体で使うような汎用目的のライブラリはアーキテクトの承認とする。他に影響しない特定目的のものは開発者の承認とするとよい。

 ここで3つのパーソナリティにいかにもそれっぽいiStockPhotoの写真が添えられていて、なるほどなあと思います。アームチェアは探偵ならいいけどアーキテクトがそれではダメなんですね。
 チームを助けリードしていく役割はマネージャーやPdMに任せときゃいいのでは?という意見には本書は強く反対していて、開発チームと共にあれ!という強い想いを感じます。

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

外向け、内側向けのコミュニケーションの章。

  • コスト、時間を理由にするのは最後の手段で他の合理的な理由を先に説明した方がよい。物事を「分割統治」で分解する。
  • 実証は議論に勝る。議論しすぎず、明確で簡潔な理由付けを元に話す。
  • 開発チームメンバを相手にするときは上から目線ではなく正当な根拠を元に。「しなくてはならない」の押し付けではなく事実を伝する。開発者が同意しない場合は自分自身で解決策を見つけてもらう。
  • 自分たちで問題を余計に複雑にしてしまう「偶発的な複雑さ」を避ける。コミュニケーション、協調性、明瞭さ、簡潔さの4つのC。
  • 想像力や知恵で未来を考える「ビジョナリー」、実践して現実的に対処する「プラグマティック」、両方のバランスを取る。
  • 人が相手の言う事に従うかは地位や肩書だけではない。技術的な知識よりピープルスキルが大事。
  • 「~すべき」「~しなくてはならない」を押し付けるのではなく、「~してみた?」「~の案は?」のような一緒に考える協調的な会話を。
  • 相手の名前をちゃんと呼ぶのも大事。
  • 握手のスキル。
  • 一方的に指図するのではなく、頼むスタンス。アーキテクト自身も人を助ける。特定の手法や技術について話すミーティングも有効。

  • 会議を減らすテクニック。参加を課されたミーティングはなぜ自分が必要なのか尋ねる。アジェンダを事前に確認する。

  • 逆にテックリードやチームメンバーを会議に参加させず、代わりに自分が参加して時間を奪わないようにするのも有効。
  • アーキテクトがメンバーを集めるミーティングも最小限に。メンバーのフロー状態を邪魔しないように、朝いちや午後いち、夕方などに。
  • なるべく開発チームに近い席に座る。そうでなかったら歩き回って頻繁に姿を見せる。

 最後にルーズベルト大統領の名言、成功の方程式の中で最も重要な成分は人とうまくやっていく方法を知ることだ...が身に染みます! このへん突き詰めていくとやはり技術でなく人の問題なんだなあと思います。
 書いてあることでは、握手のスキルなんかは欧米特有のもので日本の文化だとまた違うと思いますが、かなり頷ける内容です。

24章 キャリアパスを開く

  • アーキテクトは技術的な深さよりも「幅」が重要。ニュースフィードやWebサイト、グループ、プレゼン、Podcast、どれも良い。しかし大抵の人は忙しい。
  • そこで1日の中で「20分ルール」でこの時間をキャリア開発の情報収集に当てるとよい。おすすめは仕事を始める前の朝一番
  • 有名なThoughtWorksテクノロジーレーダーは、「ツール」「言語とフレームワーク」「手法」「プラットフォーム」の4象限で各キーワードを示している。最も外側から保留の「取扱注意(Hold)」、「評価(Assess)」、取り組む価値のある「トライアル(Trial)」、「採用(Adopt)」。これらの意味を個人用に換えて、個人のレーダーを作るのも良い。
  • ソーシャルサークルの繋がりでは家族や同僚の「強いつながり」、「弱いつながり」、まだ会っていない「潜在的なつながり」の中で「弱いつながり」が次の仕事に結びつきやすい。
  • 最後にふたたび...アーキテクチャには正解も間違いもなく、ただトレードオフがある。常に学び、練習し、アーキテクティングしよう!

  • www.infoq.com

  • dzone.com
  • www.thoughtworks.com

 世の中皆さん学習時間の確保には苦労されているかと思いますが、僕も朝活で読書の時間を取ったりしています。本書でも特に朝がオススメされていて、ここは合ってた! と思いました。最後にアーキテクティングの真理が再び示されて、アーキテクティングの基礎を巡る旅は終了です。最後には自分の理解を評価できるチェックリストもついています。

まとめ:モダンなアーキテクティングの体系的な教科書

 400ページを超える大ボリュームですが体系的に一通り、2020年代のモダンな視点、工学的な視点で記してあり、過去の歴史的経緯やコラムも豊富です。このへんの話をするにあたっての共通認識が持てる教科書的な本としても役立つでしょう。
 翻訳の島田浩二さんのブログ記事が非常に的を得ているのですが、結局トレードオフなんですよね。実際の細かなコードよりも広く上位の、このへんの抽象領域の本を読むとだいたい、唯一の正解がない世界であることが書いてあります。本書でも同じで、最善はないかもしれないが最悪を避けた選択をしていくことが大事とあります。正解に振り回されたりかざしたりしないようにしないとなあと思いました。

snoozer05.hatenablog.jp

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

おまけ:オライリー本の関連書籍

『Design It!』も同じ島田浩二さん訳、同じくアーキテクティングの領域を広く論じています。重複しているようなところ、微妙に違うところもありますがなにせ正解のない領域です、両方読んで大いに役立つと思います。
 なおこの本ではアーキテクチャの「パターン」としてレイヤードやサービスオリエンテッドアーキテクチャ(SOA)などなど...が解説されていて、このへん海外でも明確には定まっていないようですね。本書『ソフトウェアアーキテクチャの基礎』での、アーキの種類が「アーキテクチャスタイル」そしてその中でのより狭い領域を扱うのが「アーキテクチャパターン」という分類方法のほうが分かりやすいような気がします。

iwasiman.hatenablog.com

『ソフトウェアアーキテクチャ・ハードパーツ』も同じ島田浩二さん訳、2022年10月刊行。こちらは本書『ソフトウェアアーキテクチャの基礎』に収まらなかった分散アーキテクチャの諸々を解説した、続編のような本になっています。こちらもITエンジニア本大賞2023の一覧に載っていますね。

本書の17章 マイクロサービスアーキテクチャで言及されている、フロントエンド側もマイクロサービスと同じように分割していこう...という「マイクロフロントエンド」の考え方を解説したのが同名の『マイクロフロントエンド』。こちらも2022年10月刊行です。

そして世の中的にかなり早い時期にマイクロサービスを解説していた2016年2月の『マイクロサービスアーキテクチャ』も『マイクロサービスアーキテクチャ 第2版』として新しくなりました。2022年12月刊行。表紙の蜂の巣もカラーになってパワーアップ、ページ数も344→664とほとんど倍近くに大幅パワーアップ!

という感じで、最近のオライリー本がアーキテクチャ関連書籍祭りとなって賑わっています。