Amazonリンク https://www.amazon.co.jp/dp/4873119820/

読んだ理由

  • ソフトウェアアーキテクトという役割・キャリアについて興味があった。良いソフトスキル・習慣・思考などがあれば自身をアップデートしたい。
  • 主要なソフトウェアアーキテクチャパターンの知識の獲得および再確認を通じて、日々の設計業務の生産性を高めたい。

読んだ感想

  • 上記理由を満たせたので大変満足。
  • 読む前の自分の抱いていたアーキテクチャに求められるスキルは技術面に優れているイメージが強かったが、読んでみて交渉力やコミュニケーション力などのヒューマンスキルの求められるレベルの高さは、確かにな〜と盲点だった。
  • 紹介されていたアーキテクチャパターンの特性を抑えられて、引き出しが増えた気がする。スペースベースアーキテクチャなどの高度なアーキテクチャパターンを使う機会は転職以外に思いつかないが、引き出しに閉まっておこう。
  • 必要な技術知識の表現として、開発者は深さ、アーキテクトは幅が大事という表現は秀逸だった。
  • 読んで見て、アーキテクトの行う仕事とは?こんな感じか。
    • 1.ドメイン理解と組織状況をインプットして、必要なアーキテクチャ特性(illy)を導く
    • 2.上記で導いたアーキテクチャ特性を満たせる最良のアーキテクチャ案を導く。各案の良し悪し(トレード・オフ)を整理。
    • 3.関係者と認識合わせし、アーキテクチャ案の決定までを主導。決定プロセスにおける根拠を共有することで無駄な再検討を防げるのと納得感の醸成に大事。
    • 4.開発チームと協調してアーキテクチャ案を具現化。
    • 5.(初期構築はもちろん完璧じゃないので)開発イテレーションを通して継続的にアーキテクチャを磨く。

各章のメモ


## 1章: イントロダクション

- システム構造、イリティ特性、アーキテクチャ決定、設計指針を考える必要がある
- イリティ特性 (-ility)
  - 可用性 Availability
  - 信頼性 Reliability
  - テスト容易性 Testability
  - スケーラビリティ Scalability
  - セキュリティ Security
  - アジリティ Agility
  - 耐障害性 Fault Tolerance
  - 弾力性 Elasticity
  - 回復性 Recoverability
  - パフォーマンス Performance
  - デプロイ容易性 Deployability
  - 学習容易性 Learnability
- アーキテクトへの期待
  - アーキテクチャ決定を下す
  - アーキテクチャを継続的に分析する
  - 最新のトレンドを把握し続ける
  - 決定の遵守を徹底する
  - 多様なものに触れ、経験している
  - 事業ドメインの知識を持っている
  - 対人スキルを持っている
  - 政治を理解し、舵取りする
  - リーダシップスキル
- エンジニアリングプラクティス 再現性のある効果を示すプロセスに依存しない手法を意味する。e.g. CI
- 未知の未知の領域に対する予測や見積もりが人間は苦手。アジャイルはそのことを理解してより早く未知の未知に対処するように考えられたものである。
- DevOps 以前は開発と運用が別の職能と捉えれれていたのでコスト削減のため運用を別会社に委託することも多かったが、業務委託コスト削減の制約より、スケール・パフォーマンス・弾力性といった多くの能力をコントロールできるようアーキテクチャが複雑になりがち。アーキテクチャと運用を連携させることで設計がシンプルになったり運用メンバーに最適な対応を任せるメリットがあることによって出てきた考え方。
- ソフトウェアアーキテクトはトレード・オフがすべてだ。
- HowよりWhyのほうが重要である。(汎用的だから?)

# 第Ⅰ部 基礎

## 2章: アーキテクチャ思考

- アーキテクトらしく考えるとは。に関する説明の章
- 良いアーキテクトを設計をするためには、アーキテクトと開発者が実質1つのチームとなっている。プロジェクトのイテレーション・フェーズと共に変化し、開発者と蜜に連携していく必要がある。
- 技術的な深さと技術的な幅。開発者は深さ(専門性)が大事だが、アーキテクトは幅が大事になってくる。技術のメリデメ・ユースケースを知って最適解を導く役割である。未知の未知であるゆえの局所解にならないようにする努力が常に必要。
- メリット・デメリット(pros and cons) を整理して正しい問いを立てて、選定しよう。
- ビジネスドライバーを理解し、アーキテクチャ特性(-ility)に変換し、ステークホルダーと適切なコミュニケーションを取れることも求められる
- 有能なアーキテクト
  - アーキテクトがボトルネックにならないよう、クリティカルパスやフレームワークのコードは開発メンバーに任せる
    - メリット1: ボトルネックにならずにプロダクションコードに携われる
    - メリット2: オーナーシップを持ってもらえる。難しい専門性を磨ける機会を与えられる
    - メリット3: プロセス・手順・開発環境に関するチームが直面している課題の解像度・理解度が高くなる
- (自宅でコーディング練習することなく)アーキテクトが現場感を持ち続けられる工夫
  - POCを頻繁に行うこと。(その時はプロダクションレベルのコードを書こう。サンプルコードになるため模範されて質の悪いコードを拡散されるのを防ぐため)
  - 技術的な負債・アーキテクチャに関わるタスクを引き受ける (開発優先度が低いため、イテレーションの成功に影響ない)
  - シンプルなCUIツール、アナライザーによって自動化支援
  - コードレビューを頻繁にする

## 3章: モジュール性

- 凝集度:(wikipedia)モジュール内のソースコードが特定の機能を提供すべく如何に協調しているかを表す度合い
- 結合度:(wikipedia)利用者またはメンテナンスをする者にとって対象を利用、保守しやすいように対象の内容が整理、分割できているかどうかを、その状態によって段階に分けて表現する。
- (咀嚼)いくつかの指標が紹介されていたが、高凝集度・低結合度を目指して設計を心がけよう。それぞれがどんな概念が抑える程度で流した

## 4章: アーキテクチャ特性

- ソフトウェア設計時に必要なアーキテクト特性(非機能要件、illiy、 運用特性、構造特性、横断的特性等)を見極めよう。(定義・発見・分析)
- (咀嚼)すべての特性を満たすのは現実的ではないので、トレード・オフを理解し田植えで最適な特性を選ぼう。
- (咀嚼)illyはじめ、ある程度カバーされたリストが紹介されているので辞書代わりに使えそうな章

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

- アーキテクトはドメインの関心事、要件、暗黙的なドメイン知識という少なくても3つの方向からアーキテクチャ特性を明らかにできる
- 主要ドメインのゴールっや状況を理解することでアーキテクトはドメインの関心事を「イリティ(ility)」へと変換ができ、それが健全で賢明なアーキテクチャ決定の基礎となる。
- アーキテクチャ特性を決め方Tips
  - まず最初に考慮すべきはユーザー数。ユーザー数からスケーラビリティ(同時使用ユーザー数から計測)、弾力性(ユーザ数のバーストから計測)の許容度を見極めよう。
  - アーキテクト一人で決めない。ステークホルダーを巻き込もう。
  - 主なステークホルダーに最も重要な上位3つの特性を選んでもらう
  - 全てのアーキテクチャ特性を満たすのは現実的ではないので、最も重要でないアーキテクチャ特性を決定しよう。
- アーキテクチャ・カタ http://nealford.com/katas というアーキテクチャ特性を導き出す練習サイトがあるよ
- (咀嚼)「アーキテクチャ特性」と、開発者が扱う「設計上の関心事」は担当ロールが異なる?

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

- 多くのアーキテクチャ特性はより小さなスケールの他の特性から構成されている。例えばアジリティはモジュール性、デプロイ容易性、テスト容易性といった特性に分解が可能。
- アーキテクトの責務として、組織内でソフトウェア品質を確保することはアーキテクチャ統制の大項目に当たる。これを怠ると悲惨な品質問題を引き起こす。
- アーキテクチャ適応度関数 アーキテクチャ特性or特性の組み合わせについて客観的な整合性評価を行うための何らかの仕組み。
- 適応度関数はいくつか紹介されていた。循環的複雑度、循環依存など。モジュール性

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

- スケーラビリティなどのアーキテクチャ特性は、モノリスではシステム全体を指していたが、近代のエンジニアリングとマイクロサービスなどの進化によって、アーキテクチャ特性のスコープは狭くなっている。
- 運用特性を評価場合にもコードベース以外の依存コンポーネントについても考慮しなければならない。依存性を計測する概念として「アーキテクチャ量子」がある。
- アーキテクチャ特性:高度な機能的凝集性と同期的なコナーセンスを持つ、独立してデプロイ可能なアーティファクト
  - コナーセンス:システムの全体的な正しさを維持するため、あるコンポーネントの変更が別のコンポーネントの変更を必要とする場合、2つのコンポーネントはコナーセント(接続)されている。
- アーキテクチャ・カタより事例「Going、Going、Gone」のオークションサービスについての要件をアーキテクチャ特性に落とし込む考え方において、アーキテクチャ量子毎にアーキテクチャ特性を導くことで整理しやすくなると紹介されていた。
  - この事例での演習では、入札のストリーミング、オンライン入札、競売人というアーキテクチャ量子に分けて整理していた。
  - (咀嚼) 良いアーキテクチャ量子の定義をすることが大事になってくるが、ざっくりな考え方として特定のユースケースを効率的に解決するためのサブシステム?コンポーネント?的なものへのグルーピングスキルと捉えた。

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

- (この本では)コンポーネントとは モジュールが物理的にパッケージされたもの。Javaのjarファイル、Rubyのgemなどといった成果物を指す。
- アーキテクトの役割として、アーキテクチャを構成するコンポーネントを定義・改良・管理・統制する。適切な粒度で分割する。中身のクラス設計より細かい設計はテックリード・開発者に任せる。
- アーキテクチャを分割する際には最上段の分割する軸を決めることはアーキテクトの役割である。レイヤードアーキテクチャのような技術による最上位分割や、ドメインやワークフローを中心に分割する考え方ドメイン駆動開発がある。それぞれのメリデメ/トレード・オフを理解して決めることになる。
- アーキテクトが設計したコンポーネントは最初から完璧なものは作れない。全てのソフトウェア設計はイテレーションによってヒントを得て改良点が明らかになる。その原則はアーキテクト・開発者共に認識しよう。
- コンポーネント粒度を決めることは難しい。コンポーネントの発見手法として以下が紹介されていた。
  - アクター・アクションアプローチ: アプリケーションを実行するアクターとそれらのアクターが実行する可能性あるアクションを特定する。
  - イベントストーミング: DDDのアプローチ。要件および特定されたロールに基づいてシステムで発生するイベントを検討し、イベントとメッセージハンドラを中心にコンポーネントを構築する。
  - ワークフローアプローチ: DDDのアプローチ。イベントストーミングと似ているが、メッセージベースのシステム構築するという制約はない。主要なロールを明らか化にし、ロールが従事するワークフローの種類を決定し識別されたアクティビティを中心にコンポーネントを構築する。
- 1つの真の設計を見つけることに執着しないで、設計上の決定毎のトレード・オフを客観的に評価し最も悪くないトレード・オフとなるものを選ぶのが良い。


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

## 9章: 基礎

- ユニタリーアーキテクチャ: ハードとソフトウェアが単一であるシステム。組込みシステムなどの制約の多い環境以外では現在ではほとんど存在しない。パフォーマンス・スケールなどの課題があるため。
- クライアント/サーバ: デスクトップ+データベースサーバ、ブラウザ+Webサーバ、3層(データベース、アプリケーション、フロントエンド)
- モノリシックアーキテクチャと分散アーキテクチャ:
  - モノリシックアーキテクチャ: レイヤード、パイプライン、マイクロカーネル
  - 分散アーキテクチャ: サービスベース、イベント駆動、スペースベース、サービス指向、マイクロサービス
  - 分散アーキテクチャはパフォーマンス、スケーラビリティ、可用性の点でモノリシックアーキテクチャよりも遥かに強力だが、8つの誤信と呼ばれる誤解がある。
  - 誤信1.ネットワークは信頼できる
    - システムがネットワークに依存すればするほど信頼性が低下する可能性がある。
  - 誤信2.レイテンシーがゼロ
    - ローカル呼び出しの時間単位はナノ,マイクロ秒と比べてリモートアクセスプロトコルの時間単位はミリ秒単位なので、平均レイテンシーを把握した上でパフォーマンス特性を満たせるか見極めよう。
  - 誤信3.帯域幅は無限
    - サービス間の通信が帯域を大きく消費することがある。スタンプ結合を避ける工夫をしよう。最低限のデータ量でやりとりするように帯域を節約しよう。
  - 誤信4.ネットワークは安全
    - 分散アーキテクチャーに移行することで驚異や攻撃の表面積は飛躍的に増加する
  - 誤信5.トポロジーは決して変化しない
    - 接続形態(ルーター、ハブ、スイッチ、ファイアーウォール、ネットワーク、アプライアンスなどが含まれる)が変化するので、何がいつ変更されるのか関係の運用担当者やネットワーク担当者とコミュニケーションを蜜にしよう。
  - 誤信6.管理者は一人だけ
    - 分散アーキテクチャーの複雑さから、他部署との調整毎は多くなる。
  - 誤信7.転送コストはゼロ
    - 単純なRESUTful呼び出しに関わる費用面の実コスト(お金)が高くなりがち。
  - 誤信8.ネットワークは均一
    - ネットワークは複数のネットワークハードウェアベンダーを使ってインフラを作っていることがほとんどなので、各ベンダーのすべてがうまく連携しているわけではなく、全てのケースをテストしていないので、ネットワークの信頼性、レイテンシーの仮定やアサーション、帯域幅の仮定に影響を与える。
- その他考慮事項
  - 分散ロギング: ログも分散されており、原因分析も難しくなる。ログ統合の仕方を考えよう。
  - 分散トランザクション: 結果整合性を担保する手法が複雑になりがち。
  - コントラクト(契約)のメンテナンスとバージョン管理: コントラクトはクライアントとサービスの双方が合意した動作やデータ。コントラクトのメンテナンスは難しくなりがち。

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

- レイヤードアーキテクチャは技術を軸に役割を分割した一般的なアーキテクチャスタイル。プレゼンテーション層、ビジネス層、永続化層、データベース層といった形で分割される。
- ほとんどのアプリケーションの出発点として開発・インフラコストが低いので優れている。スケーラビリティや可用性などのほどんとのアーキテクチャ特性を満足に満たせないので、別のアーキテクチャへの移行を容易にしておくために適度なモジュール性を維持するようにしておくとよい。
- 解放レイヤーという各層へのアクセスを前後以外のレイヤーから可能にする考え方があるが、結合度を高くして、メンテナンス性を損ねるので、共通機能は別レイヤーとして切り出すなどのプラクティスがある。

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

- パイプラインアーキテクチャは、Unixのシェルのパイプで小さなコマンドを連結するようなアーキテクチャで、シンプルな一方通行の処理を進めるタスクで用いられる。活用例として、EDI(Electronic Data Interchange), ETL(Extract Transform Load) ツールでよく活用されている。
- モノリシックなデプロイメントとして実装されているので、アーキテクチャ量子は1つとなるため、弾力性、耐障害性、スケーラビリティといった特性は弱い。
- レイヤードアーキテクチャよりテスト容易性が若干高い傾向にある。フィルターという各シェルでいう各コマンドにあたる1処理にあたる概念により、モジュール性が高まっているため。

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

- パッケージ化され、単一のモノリシックなデプロイメントとしてダウンロード・インストールして利用するようなアーキテクチャ
  - 現在でも広く使われている Eclipse IDE, Jira, Jenkins, Webブラウザ(Chrome, Firefox, ...)といったものが一般的なプロダクト例
- 構成はコアシステムに加えてプラグインコンポーネントという概念であり、このプラグインコンポーネントにより多様なユーザーニーズへのカスタマイズ性(拡張性)と保守性を実現できる。(ex. Chrome拡張など)
  - プラグインコンポーネントに対してREST等のリモートアクセスでの接続をすることで分散アーキテクチャになりうる。分散アーキテクチャ特有の複雑とのトレード・オフは発生する。
- アーキテクチャの分割軸はドメインと技術による両方が可能な唯一のアーキテクチャスタイルである。
- コアシステムを経由しないとサービス提供できないので、モノリシックなデプロイメントとなり、アーキテクチャ量子数は常に1となる
  - レイヤードアーキテクチャと同様に、スケーラビリティ、耐障害性、弾力性などの特性は苦手。
  - プラグインコンポーネントによりモジュール性が高まるので、デプロイ容易性と信頼性は平均より上の評価。

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

- サービスベースアーキテクチャはマイクロサービスアーキテクチャのハイブリッドであり、柔軟性の高さ、分散アーキテクチャほどの複雑さや管理コストも低いため、実用的で人気なアーキテクチャである。
- 分散型のマクロなレイヤード構造を取り以下の構成を取る
  - 1:個別にデプロイされたユーザーインタフェース
  - 2:個別にデプロイされたサービス(ドメイン)粒度の粗いリモートサービス
  - 3:モノリシックなデータベース
- サービス粒度が粗くモノリシックなDBを利用しているので、ACIDトランザクションの利用が可能なので、強い結果整合性を担保できる。マイクロサービスでは保証トランザクションなどの考慮が必要。ただ、サービス粒度が粗いというのは影響範囲のトレード・オフにもなりうる。
- (咀嚼)モノリシックなデータベース(単一データベース)ではなく、複数のデータベースを使うパターンも紹介されていたので、モノリシックではある必要はなく、ある程度ざっくりした単位でDB分割し、複数のコンポーネント間で共有することでACIDトランザクションを使いたいケースで候補に上がるアーキテクチャという理解をした。
- ドメインサービスに分割していることで、アジリティ、テスト容易性、デプロイ容易性、耐障害性、可用性がレイヤードアーキテクチャと比べて高く評価されている。
- マイクロサービスと比べてサービス粒度が粗いためスケーラビリティ、弾力性は高くない。マシンリソースの点でも重複しているソースが多いため効率的ではなくインフラコストも高くなる。

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

- 高度にスケーラブルで高パフォーマンスなアプリケーションを実現でき、小規模〜大規模問わず適用性に優れている分散非同期型のアーキテクチャスタイル。
- ワークフローを管理・制御の有無で、制御不要なシンプルなブローカー型、制御可能だが複雑になるメディエーターという2つのトポロジーがある。ブローカーの弱点のワークフロー制御・エラー処理・回復性・再起動の能力・データ不整合といった欠点を解消するのがメディエーターであるが、スケーラビリティの低下、パフォーマンスの低下、耐障害性の低下、イベントプロセッサーとの結合が強くなる、複雑になるなどのトレード・オフが生じる。
  - ブローカー ソリューション: RabbitMQ, ActiveMQ, HornetQ, Amazon SQS+SNS, Pub/Sub
  - メディエーター ソリューション: Apache Camel, Mule ESB, Spring Integration, Apache ODE, Oracle BPEL
- データロスの防止: 処理が何かしらの理由で完遂できなかったときにデータロスしないように、メッセージをの永続化・クライアント応答モード、処理完了後にメッセージを削除するなどの考慮をしよう
- イベントベースモデルのメリデメ (表14-3) を理解した上で、アーキテクチャの一部にイベント駆動アーキテクチャを採用するようなバランスよく活用することも選択肢に入れよう。

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

- 違う本だが、参考の概要図 https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch05.html
- スペースベースアーキテクチャは高いスケーラビリティ・弾力性、同時実行性を実現し、ほぼ無限にスケールするアーキテクチャであるが、システムは複雑でテスト容易性は低く、高コスト(キャッシュソフトのライセンス料・インフラのリソース料)という特性がある
- 構成は以下からなる
  - アプリケーションコードを含む処理ユニット
  - 処理ユニットの管理・調整に使用される仮想ミドルウェア
  - 更新されたデータを非同期にデータベースへ送るデータポンプ
  - データポンプからの更新を実行するデータライター
  - 起動時にデータベースのデータを読み込んで処理ユニットに配信するデータリーダー
- 仮想ミドルウェア内のデータグリッドと各処理ユニット内のデータグリッドコンポーネント間でデータをレプリケートしてデータ共有をしている。
  - 各処理ユニット内のキャッシュデータを利用して処理を行う結果整合性モデルのため、キャッシュ管理の仕組み・データ衝突率が大事になってくる。
    - 扱うデータ量が多くなる場合は分散キャッシュを利用される。その場合、高レベルのデータ一貫性は保たれるがレイテンシーは増加する。

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

- 1990年代後半に、スケーラビリティなどの特性が求められた時代に開発されたアーキテクチャだが、無用の長物と評価されているアーキテクチャだが、なぜ失敗したのかその失敗の学びが後進のアーキテクチャに活かされているということが説明されていた。
- 全てのリクエストはオーケストレーションエンジンを経由する。オーケストレーションエンジンは
  - ビジネスサービスの実装をつなぐ
    - トランザクションの調整
    - メッセージ変換
  - レガシーソフトウェアとの結合ハブにもなる
- このアーキテクチャの負のトレードオフ
  - チームが再利用を主眼にシステムを構築すると、コンポーネント間には膨大な量の結合が発生し、インクリメンタルな変更時に協調的なデプロイや全体的なテストが必要となりエンジニアリングの効率性が失われた。
  - 技術による分割を重視したアーキテクチャ構築が非現実
    - トランザクションの粒度を適切なレベルで見つけ出すのが困難

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

- マイクロサービスは、ドメイン駆動設計の考え方に大きく影響を受けている。DDDの「境界づけられたコンテキスト(Bounded Context)」という分離スタイルによってシステムをドメイン(ビジネスワークフロー)毎に分離する。
- どこの境界で分割/分離させるか、また分割/分離の粒度はとても難しい。
  - 基本的にはドメインごとにDBも分散するため、モノリスではACIDトランザクションの問題にならなかったが、サービス境界を超えてトランザクションを構築したい時に問題が原子性の問題がある。基本的にはそのような問題が起きないようにサービス境界/分割粒度を見直し1DB内で結果整合性を簡単に担保できるよう設計するのが基本となる。やむをえず場合は分散トランザクションパターンであるサーガパターンが利用される。
  - 補償トランザクション(Compensating Transaction)と呼ばれる、メディエーターが全体的に成功を示すまで保留状態にして、失敗した場合は変更を取り消すDB後進処理を行うやり方が使われる。とても複雑な処理になり開発コストが高いため、利用機会は少ないほうが望ましい。
- アーキテクチャ特性として、以下の特性がある。
  - 特に高い評価: スケーラビリティ、弾力性、進化性
  - 高い評価: デプロイ容易性、テスト容易性、耐障害性、信頼性
  - 低い評価: パフォーマンス(ネットワークがボトルネックになりがち)
  - 特に低い評価: 全体的なコスト、シンプルさ
- 極端な疎結合を推進する哲学は、頭痛の種になりがちだが、うまくいけば非常に大きな利益をもたらす。

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

- アーキテクトはドメイン設計の構造に影響する様々な要因をすべて考慮しなければならない
  - ドメイン、構造沸鏡を与えるアーキテクチャ特性、データアーキテクチャ、素子的な要因、プロセス・チーム・運用上の関心事に関する知識、ドメイン・アーキテクチャの同型性(相性?)
  - モノリスか分散か?
  - データをどこに置くべきか?
    - ワークフローを構築する際にアーキテクチャ全体のデータの流れを設計しよう。
  - サービス間の通信スタイルは、同期型か非同期か?
    - 設計、実装、デバッグなどの面で課題が少ないので同期通信を標準的に使って、必要に応じて非同期通信という考え方がよい

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

## 19章: アーキテクチャ決定

- アーキテクチャ決定を下す際は、関連情報を十分に集め、妥当性を示し、文書化し、適切なステークホルダーに決定を効果的に伝える必要がある。
- アーキテクチャ決定を文書化する効果的な方法 Architecture Decision Records(ADR)の紹介。決定に必要な情報を整理したドキュメントであり、ステークホルダーとのコミュニケーションツールと設計背景をチームにドキュメントとして残す目的を果たす。
- (感想) 章の最後に紹介されているADR例がわかりやすいのでそれを見るのが早い
  - ADR 基本構造
    - タイトル
    - ステータス: 提案済み、承認済み、破棄のいずれか。破棄ステータスの理由を残しておくと、以後の無駄な検討時間を減らす効果がある。
    - コンテキスト: 「どのような状況でこの決断を迫られているか?」を簡潔に代替案と合わせて説明する。
    - 決定: 決定事項と決定に至った理由を記載する。理由を書くのが以後、無駄な議論を削減につながったりチームの学びになるのでとても重要。
    - 影響: アーキテクチャ決定時の影響(トレード・オフ)を記載し、採用時にメリットになりうるのか評価する際に有効。
    - 任意項目(推奨)
      - コンプライアンス: アーキテクチャ決定を遵守するという観点からどのような統制すべきか考える機会を提供する。
      - 備考: 追加のメタ情報となり、なにかと役に立つ。(例: オリジナル著者、承認日、承認者、更新日、変更点、最終更新内容等)

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

- リスクストリーミングの紹介。リスクの洗い出しと評価、関係者との認識合わせ、および対策を行う手法。
- 標準的なリスク評価方針として、リスク発生の可能性とリスクの全体的な影響を掛け算で数値化し、それをドメインやサービス毎に行うことでアーキテクチャ全体のリスクを評価する
- システムや外部要因で評価は変わるものなので、スポットでの実施ではなく定期的にリスク評価をしていくことが大事。

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

- アーキテクチャを図解することとプレゼンテーションをすることはアーキテクトにとって重要なソフトスキル

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

- チームの生産性を高められるアーキテクチャについて紹介されていた。
- 統制のバランス感覚、窮屈すぎると開発者のフラストレーション貯まり離任につながる。逆に緩すぎると効果的な統制ができず生産性を低下させてしまう。
- そのバランスの決め方はチーム状況・プロジェクトの特性で濃淡を調整するのが一般的
  - チームの親密さ (お互いの信頼関係が足りないチームの場合コントールが必要)
  - チームサイズ (人数がほどコントールが必要)
  - 全体的な経験 (経験が浅いメンバーが多いほどコントールが必要)
  - プロジェクトの複雑さ (複雑なほどコントールが必要)
  - プロジェクトの期間 (長いほどコントールが必要)
- チームの警告サイン
  - プロセスレス: チームの潜在能力はチーム皆の集合的な努力によって定義されるが、実際の生産性は潜在能力より低い。その差がプロセスレスとなる。頻繁にコンフリクト発生&マージ作業といったものがその例の1つ。
  - 多元的無知: 内心では否定していることに対して、自分が何かを見落としていると判断し全員が同意してしまう減少。チームを常に観察しチームをファシリテートして意見を引き出す努力が必要。
  - 責任の分散: 関わる人数が増えると事象に対する当事者意識が薄れる。
- チェックリストの活用: 手順や依存タスクがないプロセスやエラーが発生しやすいプロセス、見落とし省略が多いステップがあるチェックリストに適している。 (例:開発者のコード完成チェックリスト、忘れがちだったりエッジケースのテスト観点のためのチェックリスト、リリース時のチェックリスト)
- ガイダンスの提供: 設計指針を用いてガイダンスを提供することでチームを効果的にできる。

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

- アーキテクトが下すほぼすべての決定には異議が唱えられるため、交渉力とファシリテーションスキルが大事。関係者と良好なコミュニケーションを取る必要があり、様々なTipsが紹介されていた。
- 他のアーキテクトや開発者とのコミュニケーションにおいて、アーキテクト決定プロセスは納得感を醸成し、推進力を維持することが求められる
  - 選定の根拠を示す。ときには開発チームに結論を導いてもらうよう促すのもよい方法。
  - 強制や押し付けない。命令口調はNG。基本相手に敬意を持って接する。言い方大事。
  - コミュニケーションテクニック:
    - 相手の名前を呼ぶ頻度を上げて、親近感を醸成しよう
    - 正しい握手をしよう。目を合わせて2−3秒の短い時間でしっかり握手。ハグはハラスメントにつながるので避けよう。
    - 開発チームやステークホルダーへの気遣いを態度で示そう。常に歩き回ったりコーヒー買うついでに関係者と立ち話などをするのも良い方法。
- ビジョナリー・プラグマティックのバランス感覚を養おう。アーキテクチャの効力を長く維持するために未来含むあらゆる可能性に意識を払いつつも地に足がついた現実解を模索するような思考が求められる。

## 24章: キャリアパスを開く

- 20分ルール: 1日20分以上、アーキテクトとして何かを学ぶこと。
  - 技術の幅を広げるのが大事。「未知の未知」から「既知の未知」へ変化させることで、最適な解を選定することにつながる。
- 技術分野は投資と同じで分散するのが大事。
- アーキテクチャには正解も間違いもない。ただトレード・オフがあるだけだ。 (Neal)