サーバーレスアーキテクチャの設計で使いたいICONIXプロセス

# はじめに

サーバーレスアーキテクチャでシステムの開発をする際に、自分の場合、大体は以下のような具体的なサービス構成図から設計に入ってしまうことが多くありました。

![ICONIXサンプル-AWSサンプル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/9103ac09-79da-959e-c7b0-94e387100125.jpeg)

ただ、上記の内容って、実装レベルに近いモノであって、これまでの経験から何となく作成している感じだったんですよね。
そもそも、サーバーレスアーキテクチャについて、サービスの選択やアーキテクチャパターンの話はよく見かけるのだけれど、どのように設計していくのか、という点はあまり見かけません。

- サーバーレスを活用することで、ビジネスロジックにより集中できる
- サーバーレスを活用することで、ビジネスのアジリティが向上する

という話がある一方で、実装レベルの検討から入ってしまう状況は良くないし、実際に大きめのサーバーレスシステムを開発するとなると、いきなりアーキテクチャを具体化していくのは難しくなってきます。

そこで、今回は、自分の考えを整理すると共に、顧客のニーズやユースケースに基づき、どのようにサーバーレスアーキテクチャの設計を進めるのか、という点をまとめてみました。


# ICONIXプロセスとは？
今回の話は、簡単に言ってしまえば、**サーバーレスアーキテクチャの設計に「ICONIX(アイコニクス）プロセス」を使おう** という内容になります。 

**「ICONIX(アイコニクス）プロセス」** なんて、最近では聞いたことがない人も多いのではないかと思いますが、35歳以上ぐらいのエンジニアの人で、オブジェクト指向などをよく学習した人にとっては馴染みのある内容ではないでしょうか？（私の年齢はさておき）

ICONIXプロセスは、[「ユースケース駆動開発実践ガイド」（2007年, 翔泳社）](
https://www.amazon.co.jp/dp/B01B5MX2TC/) という書籍にて出てくる手法で、ユースケースを元に、ドメインモデリングから実装・テストまでの一連の開発の流れを示すものです。

![usecase-driven-object-modeling-with-uml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/760a4718-a12a-b661-d6ea-e172510e8600.png)

ICONIXプロセスのポイントは以下の図にまとまっています。
ユースケースを起点とする動的モデルと、ドメインモデルを起点とする静的モデルを関連付けながら、コードに落とし込んでいきます。

![iconix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/13c9aabd-2f16-2165-7de6-a2ce36e8a6eb.png)

なぜ、サーバーレスアーキテクチャでの開発で、ICONIXプロセスを利用するか、という理由については、個人的に以下の点で適合性が高いと感じるためです。

- **ユースケース／ドメインモデルといった、ユーザーのドメイン（ビジネス領域）から分析し、実装に落とし込んでいく。**
- **ロバストネス図が、サーバーレスにおけるイベントドリブンなアーキテクチャを表現しやすい。**
- **軽量で、理解するのが簡単。**

# ICONIXプロセスによるサーバーレスアーキテクチャの設計

ICONIXプロセスの概要は以下のようになります。

| プロセス | タスク | 説明 |
|----|----|----|
|要求定義|・機能要求<br>・ドメインモデリング<br>・振る舞い要求<br>・要求レビュー|最初にドメインモデルを作成し、<br>ユースケースと関連付けながら要求を整理します。|
|分析と予備設計|・ロバストネス分析<br>・予備設計レビュー|「分析」とは「正しいシステムを構築する」作業であり、<br>「設計」とは「システムを正しく構築する」作業です。<br>これらを反復的に実施することで、要求をシステムに<br>落とし込みます。|
|詳細設計|・シーケンス図の作成<br>・静的モデルの整理<br>・詳細設計レビュー|分析の結果としてまとめられた<br>ロバストネス図やドメインモデルを元に、<br>シーケンス図／クラス図を作成し、<br>設計の内容を詳細化します。|
|実装|・実装<br>・単体テスト<br>・結合テスト<br>・シナリオテスト|設計の内容に基づき、コーディング／テストを進めます。<br>（ちゃんとテストについて定義されているのも良いですね）|

本内容ではアーキテクチャ設計に主に関係する、「要求定義」「分析と予備設計」の内容について説明します。

## 要求定義

### 要件

今回は、「自転車レンタルシステム」を想定してみます。
要件は以下になりますが、内容を簡単にするため、「予約」や「料金・請求」に関するようなものは省略しています。

- 利用者は、予め会員として登録されている人が対象となる。
- 利用者は、自転車を借りられる。
- 利用者は、借りた自転車を返却できる。
- 利用者が自転車を借りたら、自動で貸出の状況が更新される。
- 利用者が自転車を返却したら、自動で貸出の状況が更新される。
- 利用者が、自転車を借りた際／返却した際に、管理者にメールが通知される。
- 管理者は、自転車一覧から現在の貸出状況を確認できる。
- 管理者は、自転車の貸出履歴を確認できる。

### ドメインモデリング
**ドメインモデリングの目的は、システムが対象とする問題領域に対して共通の用語集を作り、顧客やプロジェクトチーム内での認識ミスなどを予防することにあります。** 
ICONIXにおけるドメインモデルの作成は、DDD（ドメイン駆動開発）における「ユビキタス言語」の定義に近いものになります。

> ドメインモデリングとはプロジェクト用語集、あるいはプロジェクト内で利用される用語辞書を作成する作業です。
> ドメインモデルは皆とのやり取りの中から生み出され、成長していくモノです。プロジェクト中で洗練そして更新されるため、ドメインモデルには常に問題領域に対する現在の理解が表現されます。

ただし、難しく考えすぎないことも重要で、ICONIXでは1度の作業では2時間が目安とされています。
最初に完全なドメインモデルを目指すよりも、プロジェクト期間を通して、繰り返しモデルを洗練させていくことの方が重要になります。

さて、実際に要件から名詞を抜き出して整理すると、以下のような用語が見つかりました。

|対象|用語|
|----|----|
|アクター|利用者、管理者|
|業務|会員、自転車、自転車一覧、貸出、返却、貸出履歴|

これらの用語の関連を意識して、ドメインモデルとして図示してみました。

![ICONIXサンプル-ドメインモデル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/fbe87bc4-4ca8-3e17-e27c-726997bfd554.jpeg)


### ユースケースモデリング

一旦、ドメインモデルを作成したので、ユースケースモデリングを行っていきます。
ユースケースモデリングでは、「ユースケース図の作成」「ユースケース詳細の記述」の作業が必要になります。ここでは「ユースケース図の作成」のみを行いますが、実際のプロジェクトでは、ユースケース詳細まで記述することで、より具体的な分析を進めることができます。

ユースケースモデリングで重要なのは、**ドメインモデルで登場した単語を使って記述する**、という点になります。
ユースケースモデリング中に、ドメインモデルに登場しない用語が出てきた場合、それが本当に必要を検討し、必要であればドメインモデルへの追加を行います。

![ICONIXサンプル-ユースケース.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/90a36940-8033-9d5e-3c05-c39814ac0cf3.jpeg)

## 分析と予備設計

### ロバストネス分析

ロバストネス分析は、分析と設計の中間的な作業であり、個人的に、**このロバストネス分析が、サーバーレスアーキテクチャの設計で効果を発揮する部分**と考えています。

現代ではクラウドサービスもサービスが非常に豊富になり、同じユースケースでも、それを実現する方式やサービスは複数考えられます（例：非同期のイベントドリブンな処理をするのに、SQSを使うか、Kinesisを使うか、など）。そのため、このロバストネス分析の過程で、ユースケースを実現するためのアーキテクチャも意識しつつ、ロバストネス図にまとめていきます。

ロバストネス図は、ユースケース詳細を図として表現したもの、になります。
そのため、ロバストネス図は、システム全体で1つとではなく、ユースケースごとに記述していきます。
ただ、ここでは、内容がシンプルということもあるので、まとめて1つの図で書いてしまいます。

ロバストネス図の記述方法自体は説明しませんが、**バウンダリ／コントローラ／エンティティ**の3つの記号を使って整理していきます。

![ICONIXサンプル-ロバストネス図記号.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/e509b71a-0f21-40d9-6fa5-3dc5bcd2ac98.png)

|記号|説明|
|----|----|
|バウンダリ|システムの外部とのインタフェースとなる部分（画面、帳票、メール、APIなど）|
|コントローラ|ユースケース中でシステムが行っている処理（操作、ビジネスロジックなど）|
|エンティティ|システム内部で永続化するデータとその振る舞い（DBのテーブル、ファイルなど）|


最低限、以下のルールさえ覚えておけば、記述していくことができます。

- アクターは、バウンダリにのみに関連する
- バウンダリは、コントロールとアクターのみに関連する
- コントロールは、コントロールとバウンダリのみに関連する
- エンティティは、コントロールのみに関連する

![ICONIXサンプル-ロバストネス分析.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/5ad91a6d-a0f0-b94a-6a10-4eea94150b5f.jpeg)


ロバストネス図に登場するエンティティは、ドメインモデルに登場するものでなければいけません。
**ロバストネス分析の結果、取りこぼしに気づいたら、必ずドメインモデルを更新してください。**

サーバーレスアーキテクチャの場合、以下のような点に注意して、過不足がないかを検討しています。

- **イベントの取りこぼしがないか？**
- **同期／非同期の処理は適切か？**
- **キューを設けたり、エラーハンドリングをする部分は考慮できているか？**
- **データの特性を踏まえて、分割／アクセスできているか？**

### クラウドサービスへの置換

ロバストネス図まで作成したら、クラウドサービスへのマッピングを行ってみます。

![ICONIXサンプル-AWS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/c363d90c-88c9-12b5-6a1a-e26d19ad153b.jpeg)

今回はシンプルな内容なので、ほぼそのままマッピングできていますが、通常は、要件に対する妥当性や保守性、コストなどを鑑みて、ロバストネス図を往復しながら、検討しています。

- **エラーなどの影響でイベントを消失してしまうことがないか？**
- **永続化するサービスは適切か？**
- **性能要求を満たす構成になっているか？**

# まとめ

ほぼICONIX自体の説明になってしまいましたが、システムに対する要求を元にドメインモデル／ユースケースを検討し、そこからロバストネス分析を経由して、サーバーレスアーキテクチャの構成図に至りました。

どのような処理が必要か、それをどのようなサービスで実現するか、現代のクラウドサービスでは、複数の選択肢が考えられることも多くあり、このような分析・設計の流れを反復して、アーキテクチャに落とし込んでいくことが重要になると考えています。

モデルやアーキテクチャは、唯一の正解があるわけではなく、今回の内容も別の人が実施すれば異なるモデルになると思われますが、経験知や暗黙知のまま設計するのではなく、このようなプロセスや図を介して、顧客やチームのメンバとコンセンサスを取れるようになると良いと思っています。