20 分でわかる「ソフトウェアアーキテクチャの基礎」

# はじめに
「ソフトウェアアーキテクチャの基礎」という本を読んだので、内容について書いていきます。

https://www.oreilly.co.jp//books/9784873119823/

20 分に書籍の内容を圧縮！　……はできないので内容はかなり絞ってあります。より広範、詳細な内容については書籍の購入をおすすめします。
アーキテクトとしての在り方、キャリアパス的な話は一旦スキップします :crying_cat_face:


# アーキテクチャの定義
**ソフトウェアアーキテクチャ**は以下 4 つの構成要素を総合した概念です。
- **システムの構造**
- **アーキテクチャ特性**
- **アーキテクチャ決定**
- **設計指針**

### システムの構造
これは所謂「マイクロサービスアーキテクチャ」「レイヤードアーキテクチャ」などのアーキテクチャスタイルを表します。

### アーキテクチャ特性
システムの非機能特性です。可用性、スケーラビリティなどがこれにあたります。**今回の記事で書くのはこれの内容です。**

### アーキテクチャ決定
システムがどのような制約に従って構築されるべきかを表します。「インターネットから直接アプリケーションサーバーにアクセスできてはならない（ロードバランサを介さねばならない）」などです。

### 設計指針
これはアーキテクチャ決定のような制約ではなく、「この方針で拡張していってね」というガイドです。

# まずは大前提、アーキテクチャの第一法則
> ソフトウェアアーキテクチャはトレードオフがすべてだ。

どんなビジネス要件、状況にも適合する万能のアーキテクチャは存在しません。アーキテクチャの選定には「どのアーキテクチャ特性を優先するか」という思考が重要になります。


# 本題、アーキテクチャ特性
アーキテクチャの選定を行うには、機能的な設計だけでなく非機能的内容も考慮せねばなりません。どんなトレードオフを選択するかを考える前に、必要となるアーキテクチャ特性を明らかにする必要があります。

アーキテクチャ特性を大きく分類することは可能ですが、すべてを網羅することや「あるアーキテクチャ特性の、どんな場合でも成り立つ具体的な定義」を求めることは叶いません。どのようなソフトウェアでも、独自の要件に基づいた独自のアーキテクチャ特性を必要とするためです。

## それはそれとして、ユビキタス言語としてのアーキテクチャ特性
アーキテクチャ特性はその定義の曖昧さから、どのように設計すべきか難儀するところです。組織内でアーキテクチャ特性の客観的定義について合意しておくことで、ユビキタス言語としてアーキテクチャ特性を設計に持ち出すことができます。

また、客観的定義を行うことでアーキテクチャ特性を計測可能なものにすることができます、


## よくあるアーキテクチャ特性の例
大きくは以下のような例が挙げられます。ただし、これらの例に網羅性がないことには注意してください。
### 運用特性
|運用特性  |内容  |
|---|---|
|可用性  |システムがどのくらいの期間利用可能か  |
|パフォーマンス  |応答時間など  |
|信頼性  |障害発生時のリスクの大きさ  |
|堅牢性  |ハードウェア障害などの外乱があった際に処理に影響が出るかどうか  |
|スケーラビリティ  |リクエスト数が増えてもシステムが稼働できるかどうか  |

### 構造特性
|特性  |内容  |
|---|---|
|構成容易性  |ソフトウェアの設定のしやすさ  |
|拡張性  |プラグインによる機能拡張ができるようになっているか  |
|活用性  |別の製品でも共通のコンポーネントが使用できるようになっているか  |
|ローカライゼーション  |多言語対応  |
|可搬性  |複数のプラットフォームで動作する必要があるか  |
|アップグレード容易性  |バージョンアップが簡単におこなえるか  |

### 横断的特性
|特性  |内容  |
|---|---|
|アクセシビリティ  |色覚異常などの障害を持つユーザも利用できるか  |
|長期保存性  |データは長期保存されるか  |
|認証  |本人確認  |
|認可  |権限制御  |
|合法性  |どのような法的制約に従うか  |
|プライバシー  |他のユーザ、従業員からも個人情報を隠蔽できるか  |
|セキュリティ  |暗号化など  |
|サポート容易性  |デバッグが容易か、そもそもどのくらいのサポートが必要か  |
|ユーザビリティ  |どの程度ソフトウェアの操作に習熟している必要があるか  |


## ではどのようにして必要なアーキテクチャ特性を明らかにするか
設計者は、「ドメインの関心事」「明示的な要件」「暗黙的ドメイン知識」の少なくとも 3 つの側面からアーキテクチャ特性を明らかにできます。

### ドメインの関心事から抽出する
ドメインの関心事というのは、謂わば経営陣、ステークホルダの関心事です。開発者は「アーキテクチャ特性」というユビキタス言語を使えますが、多くの場合これはステークホルダの言語とは異なります。

設計者は、ドメインの関心事をアーキテクチャ特性に変換しなくてはなりません。例えば次のような変換ができます。

|ドメインの関心事  |アーキテクチャ特性  |
|---|---|
|合併・買収  |スケーラビリティ、拡張性など  |
|市場投入までの時間  |テスト容易性、デプロイ容易性など  |
|ユーザ満足度  |パフォーマンス、可用性、セキュリティなど  |
|競争優位性  |アジリティ、スケーラビリティ、可用性など  |
|時間・予算  |シンプルさなど  |

「など」と書いてありますが、これは単一のドメイン関心に対して単一のアーキテクチャ特性を選択すればよいということを指してはいません。常に複数のアーキテクチャ特性の組み合わせを考える必要があります、

例えば、スケーラビリティに優れていても可用性を欠いたアーキテクチャに競争優位性を見出すのは難しいでしょう。

### 要件から抽出する
要件定義にそもそも明示されている場合もあります。

### 暗黙的ドメイン知識から抽出する
要件文書にそもそも書かれているようなアーキテクチャ特性とは異なり、明示的ではないもののプロジェクトの成功には欠かせない特性も存在します。

例えば、リアルタイムなオンラインゲームを提供する会社であれば、低レイテンシをあえて要件に挙げなかったとしてもそのアーキテクチャ特性の重要性は推して知るべしです。そしてこれは、問題領域の知識からおのずと導き出される内容です。


## 特性はつかめた！次は …… アーキテクチャ特性のコントロール
技術、ビジネスのトレンドや法律などさまざまなものの変化に対応して進化するアーキテクチャを**進化的アーキテクチャ**と呼びます。
**進化的アーキテクチャ**においては、アーキテクチャ特性の組み合わせについての整合性評価を行う**適応度関数**を定義します。

### 適応度関数
適応度関数は、単体テストやメトリクス、カオスエンジニアリングに至るまで多種多様な既存の検証方法と重なります。

これは設計者が重要なアーキテクチャの方針を表現して、それを自動的に検証するための仕組みを提供するものです。

例えば、活用性に関する適応度関数としては、「モジュールの循環依存が存在しないことをチェックする」などがあり得ます。モジュールの循環依存があると、単一のモジュールが再利用できなくなるためです。この適応度関数を CI などに組み込めれば製品のアーキテクチャ特性を自動的に保証させることができます。

# アーキテクチャスタイル
**アーキテクチャスタイル**はシステムを作るソースコードがどのように編成されていて、データストアとどのように相互作用するかを表す包括的な構造と定義されます。

レイヤードやマイクロサービスなどの有名なアーキテクチャスタイルは特定の問題に対応するためのさまざまなトレードオフを体現しています。


## 例: マイクロサービスアーキテクチャ
マイクロサービスは有名なアーキテクチャスタイルのひとつです。

マイクロサービスは通常、各々のサービスがその単一目的の性質を実現するのに十分な大きさでしかありません。それゆえ、他の分散アーキテクチャよりもずっと小さいものになります。

### ドメインドリブンなアーキテクチャスタイル
マイクロサービスの概念は DDD に大きく影響を受けています。すなわち、全てのサービスの境界はドメインに対応づかなくてはなりません。
ドメインにおける目標や、施策の境界をサービスの境界に反映するのが自然と考えられます。

### 粒度
分割したマイクロサービスの粒度が小さければ小さいほどサービス間での通信による全体に対するパフォーマンスの影響が大きくなります。設計者はマイクロサービスの、目的のための適切な粒度を考えなければなりません。

粒度のトレードオフに適切に対処し、サービス間の境界を見出すのに役に立つ方針があります。
#### サービスの目的
理想的には、各マイクロサービスは機能的にまとまっていて、アプリケーション全体を通して 1 つの重要な動作を提供するように設計されるべきです。

#### トランザクション
トランザクションは分散アーキテクチャでは問題の温床になります。できるだけ避けるように設計されるのが良いです。

#### コレオグラフィ
サービスの分割によって、ある機能が動作するのに広範な通信が必要になる場合はこれを大きなサービスにまとめることで通信のオーバーヘッドを回避できます。

ただ、コレオグラフィパターンは処理順序によってサービス間依存が強くなりやすく一長一短です。

### アーキテクチャ特性の評価
デプロイ容易性、弾力性、モジュール性などは高くなる傾向にあります。また、各サービスの境界が明確であればテスト容易性も十分にサポートできます。

ただ、分散アーキテクチャ特有の欠陥も抱えており、その 1 つがパフォーマンスです。

# おわりに
「ソフトウェアアーキテクチャの基礎」の内容について、アーキテクチャ特性を中心に触れました。
アーキテクチャ特性の内容だけでも触れきれてない部分もあります。

特に、有名なアーキテクチャスタイルについてまとまっている第Ⅱ部は読んで損のない内容だと思います。本を買ってください。