⚙️はじめに
掲題の通り、『ソフトウェアアーキテクチャの基礎―エンジニアリングに基づく体系的アプローチ』を読み終えたので、まとめておく。
本書は以下の章立てで構成されている。
- 1章:イントロダクション
- 第Ⅰ部 基礎
- 第Ⅱ部 アーキテクチャスタイル
- 第Ⅲ部 テクニックとソフトスキル
本ブログでは上記の章立て通りにはまとめず、以下の粒度でまとめる事とする。
- 本書に出てくるアンチパターンと回避方法
- ソフトウェアアーキテクチャの概観
- ソフトウェアアーキテクチャのスタイル
- アーキテクトについて
- アーキテクトにキャリアパスがないと言われている所以
- アーキテクトに期待する事
- アーキテクトのパーソナリティ
- アーキテクトが意識すべき事
⚙️本書に出てくるアンチパターンと回避方法
象牙の塔アーキテクトアンチパターン
- 発生:開発チームの意見や懸念を無視して、上から目線で何をすべきかを指示しているだけのアーキテクト
- 回避:開発チームとコミュニケーションを取り、協働してアーキテクチャ決定を下す
汎用アーキテクチャアンチパターン
- 発生:すべてのアーキテクチャ特性をサポートしようとして、システム全体が複雑になる
- 回避:設計をシンプルに保つ。最も重要な特性3つを顧客に決めてもらう。
巨大な泥団子アンチパターン
暗黙のアーキテクチャアンチパターン
偶発的アーキテクチャアンチパターン
アーキテクチャシンクホールアンチパターン
- 発生:「レイヤードアーキテクチャ」において、各レイヤー内でビジネスロジックが実行されず、リクエストがパススルーされてレイヤー間を移動してしまう
- 回避:80対20ルールに従う。すべてのレイヤーを開放レイヤーにする。
資産防御アンチパターン
- 発生:選択誤りの恐れによる、選択や決定の放棄や先延ばし
- 回避:最終責任時点まで決定を下さない。決定が実現できるように開発チームをサポートする。
グラウンドホッグデーアンチパターン
- 発生:決定が下された理由の周知不足。
- 回避:ビジネス価値を付加して、周知・共有する。
メール駆動アーキテクチャアンチパターン
- 発生:メンバーは決定を失念・忘却してしまう。
- 回避:本当に関心のある人にだけ決定を伝える。メールではなくWikiにする。
アーティファクトへの不合理な愛着アンチパターン
- 発生:アーキテクトが自分が作ったものに過度に執着してしまう。
- 回避:UML、C4、ArchiMateなどを用いて手早く作る。
クッキー型アンチパターン
- 発生:プレゼンテーション作成者が、スライドを余計な装飾で埋め尽くそうとする
- 回避:1つのスライドで全てを表現しようとせず、複数のスライドに分けてアイディアを表現する
蜂の巣にされた死体アンチパターン
- 発生:スライドがプレゼンテーション発表者のメモでしかない状態
- 回避:プレゼントは「視覚」「聴覚」の2つの情報チャンネルがあるので、うまく使い分ける
⚙️アーキテクチャの概観
ソフトウェアアーキテクチャの法則
ソフトウェアアーキテクチャのモジュール性とコンポーネント
モジュール性
ソフトウェアアーキテクチャに関する言説の95%は「モジュール性」の利点を称賛するために費やされる。
「モジュール性」を計測するには、以下3つのメトリクスがある。
凝集度
- 尺度としては、以下7段階がある
- 機能的凝集
- 逐次的凝集
- 通信的凝集
- 手続き的凝集
- 時間的凝集
- 論理的凝集
- 偶発的凝集
結合度
- 種類としては、以下2つがある
- これに関連する用語は以下の通り
コナーセンス
コンポーネント
「コンポーネント」とは、モジュールが物理的にパッケージ化されたものであり、アーキテクチャの基本構成要素。
- 細か過ぎる:コンポーネント間でたくさんのやりとりが必要になり、一貫性やトランザクションなどの管理が困難になる
- 粗過ぎる :内部結合度合いが高くなり、デプロイ容易性やテスト容易性の確保が困難になったり、モジュール性に関連した負の副作用をもたらす
コンポーネントの発見には、以下などがある
- アクター/アクションアプローチ
- ワークフローアプローチ
- イベントストリーミング
ソフトウェアアーキテクチャの構成要素
ソフトウェアアーキテクチャは、以下4つから構成される。
構造
システムで使われているアーキテクチャスタイルの種類(詳細は次章で記載)であり、以下のようなものがある。
- ユニタリーアーキテクチャ
- 一元的なアーキテクチャ
- (組込み系では今でも採用されている)
- 2層アーキテクチャ
- クライアント・サーバシステム
- (少し派生して「3層アーキテクチャ」もある)
- モノリシックアーキテクチャ
- レイヤード
- パイプライン
- マイクロカーネル など
- 分散アーキテクチャ
- サービスベース
- イベント駆動
- スペースベース
- サービス指向
- マイクロサービス など
モノリシックアーキテクチャでは「ACIDトランザクション」が採用される事が多い。
- A(Atomicity)
- C(Consistency)
- I(Isolation)
- D(Durability)
分散アーキテクチャでは「BASEトランザクション」が採用される事が多い。
- BA(Basically Available)
- S (Soft state)
- E (Eventual consistency)
分散アーキテクチャはモノリシックアーキテクチャよりも強力だが、以下8つの誤信を注意する必要がある。
上記8つの誤信の他にも、分散アーキテクチャは、以下について注意する必要がある。
アーキテクチャ特性
システムがサポートしなければならない「イリティ(-ility)」であり、以下のようなものがある。
- 可用性
- 信頼性
- テスト容易性
- スケーラビリティ
- セキュリティ
- アジリティ
- 耐障害性
- 弾力性
- 回復性
- パフォーマンス
- デプロイ容易性
- 学習容易性 など
アーキテクチャ特性とは、以下3つを満たすものをいう。
- ドメインに依らない、設計に関する考慮事項を明らかにするもの
- 設計の構造的な側面に影響を与えるもの
- アプリケーションの成功に不可欠ないし重要なもの
アーキテクチャ特性を全乗せした「汎用アーキテクチャアンチパターン」にならないようにする。
- 常にトレードオフを意識する
- 最も重要な特性3つを顧客に決めてもらう
アーキテクチャ特性は、以下の特徴を持つ「アーキテクチャ量子」で定め、スコープを絞って考える。
- 独立してデプロイ可能
- 高度な機能的凝集性
- 同期的なコナーセンス
アーキテクチャ特性を【明確】にするには、「アーキテクチャ・カタ」を用いてみるとよい。
- 「アーキテクチャ・カタ」には、明確にするのに必要な「関心事」「要件」「暗黙的なドメイン知識」が含まれる
- 要件定義には、"明示的な特性"は記載されているものの、"暗黙的な特性"は記載されていないため、カタを用いて明確にする
アーキテクチャ特性を【計測】するには、以下の客観的指標を用いる。
- 運用面の計測 :パフォーマンスなど
- 構造面の計測 :循環複雑度など
- プロセス面の計測:テスト容易性など
アーキテクチャ特性を【統制】するには、以下を用いる。
- XP(エクストリームプログラミング)
- CD(継続的デリバリ)
- DevOps など
アーキテクチャ特性を【検証】するには、以下のような適応度関数を用いる。
- メトリクス
- 監視
- ユニットテスト
- カオスエンジニアリング など
例として、可用性については「9」を意識して設定する。
- システム全体としてはファイブナイン(99.999%)である必要がない事もあるので、分割統治も考える。
アーキテクチャ決定
システムを構築する際のルール(ガイドラインではない)であり、以下のような例がある。
- <例>レイヤードアーキテクチャの場合
- ビジネス層とサービス層は、永続化層に直接アクセスできる
- プレゼンテーション層は、永続化層に直接アクセスできない
- サービス層は、開放レイヤとする
- サービス層意外は、閉鎖レイヤとする など
アーキテクチャ決定については、以下のようなアンチパターンが段階的に発生する事がある。
アーキテクチャ決定を文書化するには、「アーキテクチャデシジョンロード(ADR)」を用いるとよい。
設計指針
システム構築する際のガイドライン(ルールではない)であり、以下のような例がある。
- <例>マイクロサービスアーキテクチャの場合
- サービス間の非同期メッセージングを可能な限り活用し、パフォーマンスを向上させる
- (ルールとして堅く決める事が難しい指針を示すのが目的)
⚙️ソフトウェアアーキテクチャのスタイル
前述した4つの構成要素のうち「構造」について、以下に詳しく記載する。
モノリシックアーキテクチャ
レイヤードアーキテクチャ
- 別称
- n層アーキテクチャ
- 構成要素
- レイヤの種類
- プレゼンテーション層
- ビジネス層
- 永続化層
- DB層
- レイヤの分類
- 開放レイヤ:追加に強いが変更に弱い
- 閉鎖レイヤ:追加に弱いが変更に強い
- レイヤの種類
- 特徴
- コンウェイの法則が働く組織で採用されがち
- 各レイヤの作業は抽象化されており、各レイヤで役割と責務を持つ
- 小規模でシンプルなアプリケーションやWebサイトには向いている
パイプラインアーキテクチャ
- 別称
- パイプとフィルターアーキテクチャ
- 構成要素
- パイプ
- 一方向かつポイントツーポイント
- フィルター
- ステートレスでシングルタスク
- 「プロデューサ」「トランスフォーマ」「テスタ」「コンシューマ」から構成される
- パイプ
- 特徴
- Linuxのパイプラインが代表的
- 拡張性に優れている
マイクロカーネルアーキテクチャ
- 別称
- 構成要素
- 特徴
分散アーキテクチャ
サービスベースアーキテクチャ
- 別称
- なし
- 構成要素
- 特徴
- 柔軟性が高く、実用的で、ドメインによって分割されるアーキテクチャ
- サービスの粒度は、以下のトレードオフを持つ
- 細かくなるにつれて、「オーケストレーション」と「コレオグラフィ」にまつわる問題が出てくる
- 粗くなるにつれて、完全性や一貫性は向上するものの、テスト容易性などが欠如する可能性がある
イベント駆動アーキテクチャ
- 別称
- なし
- トポロジ(構成要素とは違う)
- ブローカー
- 分離され独立していてシンプルなため拡張性が高い
- 単一障害点が発生しやすく、非同期処理なのでどこで問題が発生しているか分かりづらい
- メディエーター
- ワークフローに関する知識と制御を持ち、単一障害点も解消できる
- 結合度が高いため複雑になりがち
- ブローカー
- 特徴
- 非同期には「リクエスト・リプライ」「ファイア・フォーゲット」があるが、いくつかの問題を抱える
- エラー処理:解決方法は、ワークフローの委譲
- データロス:解決方法は、メッセージング技術やACID特性
- 非同期処理だけでなく、必要に応じて同期処理も検討すべき
- 非同期には「リクエスト・リプライ」「ファイア・フォーゲット」があるが、いくつかの問題を抱える
スペースベースアーキテクチャ
- 別称
- なし
- 構成要素
- 特徴
オーケストレーション駆動サービス指向アーキテクチャ
- 「分離」と「再利用」によって効率化を図るつもりが、一つの変更が全てのサービスに影響を及ぼすという、非効率を生み出してしまっている
- (「再利用」により「結合」が発生し、結合度が上がってしまうという負のトレードオフ)
マイクロサービスアーキテクチャ
- 別称
- なし
- 構成要素
- 特徴
- ドメイン駆動型設計(DDD)の考え方に影響を受けている
- 高度な分離のために、再利用よりも複製を選んでいる
- 境界づけられたコンテキストの論理的概念を、物理的にモデル化している
- マイクロサービスアーキテクチャの通信は、プロトコルを意識した異種間相互運用性を利用する
- コレオグラフィでは、複雑度が増す
- オーケストレーションでは、結合度が増す
- サービスを跨いだトランザクションは作らない
- もし作るなら「サーガパターン」を用いるとよいが、そもそも作るべきではない
⚙️アーキテクトについて
アーキテクトにキャリアパスがないと言われている所以
ソフトウェアアーキテクトに明確なキャリアパスがない理由は、以下の4つ。
- ソフトウェアアーキテクチャ自体の定義が業界でよく定まっていない
- ソフトウェアアーキテクトの役割が非常に広範囲にわたり、拡大を続けている
- ソフトウェア開発エコシステムが急速に進化しているために、ソフトウェアアーキテクチャが常に変化する対象になっている
- ソフトウェアアーキテクチャについての資料の大半が、単なる歴史的経緯になってしまっている
アーキテクトに期待する事
アーキテクトは、以下である必要がある。
- プログマティック
- ビジョナリー
また、「アーキテクトらしく考える」ために必要な事は、以下の通り。
- アーキテクチャと設計の違いを理解する
- 違いなんてものは存在しないので、チームの壁を取っ払って、コラボする
- (違いを決めてしまうと分業してしまい、最も重要な"コラボレーション"が失われるため、敢えて違いを設けないという意味)
- 広範的な技術知識を持つ
- 開発者は深さ、アーキテクトは広さ
- (ここを履き違えると、機能不全に陥る)
- トレードオフの理解・分析・調整する
- ビジネスドライバーを理解する
つまり、アーキテクトに期待する事は、以下8つ。
- アーキテクチャ決定を下す
- アーキテクチャを継続的に分析する
- 最新のトレンドを把握し続ける
- 決定の順守を徹底する
- 多様なものに触れ、経験している
- 事業ドメインの知識を持っている
- 対人スキルを持っている
- 政治を理解し、かじ取りする
アーキテクトのパーソナリティ
アーキテクトのパーソナリティは、以下3タイプに分類される。
- コントロールフリークアーキテクト:きつめ。開発チームに制約を与え過ぎてしまい混乱を招く。
- アームチェアアーキテクト:ゆるめ。開発チームに作業が集中してベロシティと生産性が低下する。
- 効果的なアーキテクト:ちょうどいい。エラスティックリーダーシップを取れる。
アーキテクトが、どの程度コントロールフリークで、どの程度アームチェアであるべきかは、以下により変動する。
- チームの親しさ(親しければ緩くていいし、組立てのチームならキツめでいい)
- チームのサイズ(小さければ緩くていいし、大きければ多少の制約は必要)
- 全体的な経験(シニアが多ければ緩くていいし、ジュニアが多ければ制約やメンタリングが必要)
- プロジェクトの複雑さ(シンプルなら緩くていいし、複雑なら統制が必要)
- プロジェクトの期間(短ければ緩くていいし、長ければ統制が必要)
アーキテクトが意識すべき事
アーキテクト自身がボトルネックにならず、かつ現場感が保てるように、以下の方法を取る
- PoCを頻繁に行う
- ストーリーを引き受ける
- イテレーション内でバグ修正に取組む
- 日常業務を自動化する
「本質的な複雑さ」は仕方ないが、「偶発的な複雑さ」を生まないように、以下の4Cを行う
- Communication(コミュニケーション)
- Collaboration(協調性)
- Clarity(明瞭さ)
- Conciseness(簡潔さ)