入門ソフトウェアアーキテクチャ4種

:::note info
新たにソフトウェアアーキテクチャの本を出しました。
この記事よりも**圧倒的におすすめ**です。ぜひご一読ください。

**「[【図解】ストーリーでわかる！ソフトウェアアーキテクチャ14選](https://zenn.dev/mossan_hoshi/books/b2326637fec195)」**
- 全文無料
- 主要アーキテクチャ**14種**の雰囲気を物語で掴める
- 各アーキテクチャイメージ**画像**付き
- **pythonコード、クラス図**付き
- 計**4万6千字**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/927bcb68-a23b-7bc4-6bb6-69e9b9dbf89b.png)
:::

# TLDR
- 4種のSWアーキテクチャの紹介
    - **アーキテクチャはトレードオフ** 。必ずメリット・デメリットが存在する

|アーキテクチャ名|概要|メリット|デメリット|変更容易性|デプロイ容易性|テスト容易性|パフォーマンス|スケーラビリティ|開発容易性|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|
|階層型アーキテクチャ|OSI参照モデルのように階層式にアクセスする構造|隣接層同士以外は基本疎結合にできる|データをバイパスすると簡単に疎結合が崩れる(sinkhole anti-pattern)|✖|✖|🔵|✖|✖|🔵|
|イベント駆動型アーキテクチャ|メディエーターもしくはリレー構成(ブローカー)により非同期アーキテクチャを実現|モジュールを疎結合に保ち大規模アプリを実現可能|比較的複雑。<br/>一般の分散アーキテクチャに起こる問題が発生|🔵|🔵|✖|🔵|🔵|✖|
|マイクロカーネルアーキテクチャ|パッケージ形式のアプリ向き|- 独立したプラグインを自由に追加/削除可能<br/>- このアキテクチャ自体を他のアーキテクチャに組み込み可能|● 単一マシンでの稼働が前提<br/>● プラグイン―カーネル間のコントラクトをしっかり定義しておく必要あり|🔵|🔵|🔵|🔵|✖|✖|
|マイクロサービスアーキテクチャ|一番重要。階層化アーキテクチャ／SOAから発展|SOA等の課題を解決|● コンポーネントの粒度決定が難しい<br/>● DRY原則違反が起こりがち|🔵|🔵|🔵|✖|🔵|🔵|

# 備考
- 本記事の内容は以下のレポートを参考にしています
- 「Software Architecture Patterns」(2015)
    - 50ページ程度の小冊子に代表的なアーキテクチャパターン5種が紹介されています
      1. 階層化アーキテクチャ
      2. イベント駆動型アーキテクチャ
      3. マイクロカーネルアーキテクチャ
      4. マイクロサービスアーキテクチャ
      5. スペースベースのアーキテクチャ(Space-based Architecture)
            - 本書ではこのアーキテクチャは扱いません 

https://learning.oreilly.com/library/view/software-architecture-patterns/9781491971437/


# アーキテクチャの紹介
## 1. 階層化アーキテクチャ(Layered Architecture)
### 概要
- 基本のアーキテクチャ(迷った時はまずこのアーキテクチャから開始して、後から別のアーキテクチャにするのも良い）
- 一般的には下記4層で構成される
    - プレゼンテーション層
    - ビジネス層
    - 永続化層
    - データベース層
- 【構成】
```plantuml
@startuml
!theme spacelab
top to bottom direction
skinparam actorStyle awesome

rectangle プレゼンテーション層 {
  component 1_1
  component 1_2
}
rectangle ビジネス層 {
  component 2_1
  component 2_2
}
rectangle   永続層 {
  component 3_1
  component 3_2
}
rectangle データベース層 {
  database DB1
  database DB2
}

リクエスト .down.> プレゼンテーション層
プレゼンテーション層 ..> ビジネス層
ビジネス層 ..> 永続層
永続層 ..> データベース層


@enduml
```

### 利点
- 隣接する層同士以外は(基本)互いに疎（結合度の低い設計が可能） 
- 実装が用意
### 欠点
- 基本はモノリシックシステムかつ小規模向け
- 「陥没穴アンチパターン(sinkhole anti-pattern)」に容易になりえる
    - 前段の層から渡されたデータをバイパスして次の層にそのまま渡す等の処理を入れてしまうと、離れた層同士が結合状態になってしまう
```plantuml
@startuml
!theme spacelab
top to bottom direction
skinparam actorStyle awesome

rectangle プレゼンテーション層 {
  component 1_1
  component 1_2
}
rectangle ビジネス層 {
  component 2_1
  component 2_2
}
rectangle サービス層 {
  component 3_1
  component 3_2
}
rectangle   永続層 {
  component 4_1
  component 4_2
}
サービス層 ..> 永続層
rectangle データベース層 {
  database DB1
  database DB2
}

リクエスト .down.> プレゼンテーション層
プレゼンテーション層 ..> ビジネス層
ビジネス層 ..> サービス層
ビジネス層 ..> 永続層
永続層 ..> データベース層


@enduml
```

## 2. イベント駆動型アーキテクチャ
### 概要
- イベントをキューもしくはメッセージトピックを介してやり取りするアーキテクチャ
- 実装形態として中央管理機構(メディエーター)が存在する「メディエータートポロジー」と数珠繋ぎで処理を実行する「ブローカートポロジー」の2種が存在する
#### メディエータートポロジ
- ある程度のオーケストレーションを必要とするアプリ向け
- 中央管理処理コンポーネントであるイベントメディエーターがオーケストレーションの役割を担い、各イベントプロセッサーにイベントの受け渡しを行う。イベントプロセッサー内には複数のモジュールがあり、要求された処理を実行する
- 全体の処理はメディエーターに初期イベントが投げられてから開始する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/198e19d9-8325-7eb4-bc43-87b21a8512b0.png)

#### ブローカートポロジ
― メディエーターがおらず、各イベントプロセッサーが処理が終わったら次のキューにイベントを渡して **数珠繋ぎ** で処理がハンドリングされる
- 細かい制御が不要なアプリ向け
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/65199875-75f5-3393-3cc0-02ae89e4f8bb.png)
### 利点
- スケーラブル(大規模アプリケーションにも対応可能）
### 欠点
- トランザクションがビジネスプロセス単位に閉じていない
    - イベントプロセッサーが細かく分けられているため、複数のトランザクションが混ざり合ってしまう(分離が必要な際に手間がかかる）
- イベントプロセッサーのコントラクト（入出力形式仕様）の管理が大変
    - 例：コントラクトのバージョン変更をする際に複数のバージョンに整合性をどうとるかが難しい
## 3. マイクロカーネルアーキテクチャ
### 概要
- パッケージ(製品)向けのアーキテクチャ
- 中央カーネルとそれに繋がるプラグインの構成
- 重要なことは「プラグイン間の通信を行わない(結合度を下げる）」「コントラクトをしっかり決めておく」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/5e2d6d89-6b71-6e1f-1bad-cdc5ff90a62b.png)

### 利点
- 他のアーキテクチャの一部として本アーキテクチャを組み込める
- 段階的な開発が可能
### 欠点
- モノリシックサービス向け（大規模アプリの1サービス内に本アーキテクチャを埋め込む等の対応は可能）
## 4. マイクロサービスアーキテクチャ
### 概要
- 階層化アーキテクチャパターンを使用して開発されたモノリシックアプリケーションと、サービス指向アーキテクチャパターンを介して開発された分散アプリケーションの2つから進化した形のアーキテクチャ
- サービス間の依存を極力排し、オーケストレーションを不要にする事で複雑なアプリの実現に対応している
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/a864d7c9-4400-c49c-a92e-2946b38de207.png)

- 実装形態はさまざまあるが、代表的なものは以下の3種
#### 1. API RESTベーストポロジ
- 各サービスにREST APIでアクセスする構成
- サービスの単位は非常に小さくする
- 小さな自己完結型Webサイトなどで使われている
#### 2. アプリケーションRESTベーストポロジ
- サービスコンポーネントはAPI RESTベースよりも大きく粗い
    - 1つのサービスコンポーネントが1つのビジネス機能に相当する粒度
- リクエストも複雑なデータをやり取りする
#### 3. 集中型メッセージングトポロジ
- RESTの代わりにメッセージブローカー(AmazonMQ、RabbitMQ等)を使用する以外はRESTベースとポロジに似ている
    - RESTと比べてキューイングの仕組みが高度だったり、負荷分散／スケーリングの点で優位
### 利点
- サービスの追加・更新が容易
- オーケストレーション機能が不要
    - どうしてもオーケストレーション機能が必要な場合はそもそもマイクロサービスアーキテクチャに適していないサービスの可能性がある
- サービス同士が疎結合
    - どうしてもサービス間通信が必要な場合、共有データベースを介して結合を避ける事を検討する余地あり
### 欠点
- サービスコンポーネント粒度決定が難しい
    - 細かすぎると従来の分散システム（SOA）の問題が発生してしまう
    - 粗すぎるとマイクロサービスアーキテクチャの利点が損なわれる（モノリシックアーキテクチャに近づく）
- DRY原則違反しやすい
    - 同じ機能が複数サービスに点在しがち


# 最後に
- 現在アーキテクチャ本「[Fundamentals of Software Architecture](https://learning.oreilly.com/library/view/fundamentals-of-software/9781492043447/)」を読んでいるんですが、内容が濃くボリュームも多いのでなかなか読み進められていませんでした。上記のオライリーレポートはこの本のエッセンシャル版に当たる本でして、サクッとソフトウェアアーキテクチャの概要に触れることができて非常に助かりました。古いですが短くて初心者におすすめのレポートです(「[Software Architecture Patterns](https://learning.oreilly.com/library/view/software-architecture-patterns/9781491971437/)」(2015))

https://learning.oreilly.com/library/view/fundamentals-of-software/9781492043447/