マイクロサービスのサービス分割時において、ロバストネス分析が有効なのかを考える

# この記事を読んで分かること

この記事では、ロバストネス分析の基本を理解していただくこと、また、マイクロサービスのサービス分割時にロバストネス分析を活用するというアイデアを共有することができればと考えています。

* ロバストネス分析とは
* ロバストネス分析の目的
* ロバストネス図の見方
* マイクロサービスのサービス分割時において、ロバストネス分析を活用するアイデアとその理由

# はじめに

どのようにサービス分割していくべきかについて、これまで自分が見てきた事例をベースとして、自分なりに考察したことを記載したいと思います。

前半では、ロバストネス分析とその成果物であるロバストネス図の概要について記載します。後半では、システムをマイクロサービス化する時に生じる「サービスをどこで分割していくか」という課題に対して、ロバストネス分析がひとつの有効な手段になるのではないかというアイデアを考察と共に記載します。

ネット上においてもDDD（ドメイン駆動設計）の中でロバストネス分析を活用する事例も散見されており、今後、そのロバストネス分析というキーワードを見る機会が増えてくるかもしれません。そこで、この記事を読んでもらうことによって、ロバストネス分析とロバストネス図の概要について把握し、そのキーワードを見た時に思い出していただければと考えています。

この記事ではDDD（ドメイン駆動設計）やマイクロサービスの基本については解説していません。すでに前提知識としてお持ちであることを想定していますので、ご了承ください。最後に参考となるサイトを紹介していますので、それらも参考にしていただければと思います。

# ロバストネス分析とは

一般的にロバストネス分析は予備設計として詳細設計前に実施されます。ロバストネス分析を行うことによって詳細設計に必要な要求モデル（ドメインモデル(※)やユースケース記述、ユースケース図）をロバスト（堅牢、強靭）にすることができます。

システムのユースケース記述をもとに、システムを「バウンダリ」「エンティティ」「コントローラー」の三つに分けて分析します。その分析の過程で、要求モデル（ドメインモデルやユースケース記述、ユースケース図）の不足、疑問点、曖昧な個所を抽出し、改善するきっかけとなるようにします。

![icon-sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/5c2627ad-871c-5c84-affb-099292d4b886.png)


ロバストネス分析はソフトウェア分野における統一モデリング言語（UML）を開発したスリーアミーゴスの一人であるイヴァー・ヤブコソンによって提唱された分析手法です。この分析手法自体は新しいものではありませんが、マイクロサービスの設計手法として注目されているDDD(ドメイン駆動設計)を行う場面においても活用されることもあります。

※ドメインモデル（英: Domain model）は、システムに関わるさまざまな実体とそれらの関係を説明するシステムの概念モデルである。（https://ja.wikipedia.org/wiki/ドメインモデル より引用）

# ロバストネス分析の目的

以下を実現するためにロバストネス分析を行います。

1. 設計の静的モデルのインプットとなること  
要求モデルをロバストネス分析により明確にすることによって、後続の静的モデルの作成（詳細設計）が行いやすくなります。例えば、ICONIXプロセスでは、ユースケース作成後にロバストネス図を作成し、その後、UML静的モデリングを行う手順としており、ロバストネス図が静的モデリングのインプットとなっています。(※)

1. ユースケース記述の曖昧さをなくすこと  
ユースケース記述に従ってロバストネス図を作成しようとしても表現できないことが判明したり、ユースケース記述が曖昧であったり不足していたりして加筆・修正すべき箇所が明らかになる場合があります。この時は、ユースケース記述を見直します。

1. 見逃していたオブジェクトを発見すること  
ロバストネス図を作成していると、それまでに作成してきたユースケース記述には表れてこなかった語彙や概念が出てくることがあります。

1. オブジェクトを適切な単位にまとめることができること  
ユースケース記述から分析レベルのオブジェクトを見つけ、適切な単位にまとめることができます。

※ユースケース記述の潜在的な間違いを検出するためにロバストネス分析を実行し、それに応じてドメインモデルを更新する。（https://ja.wikipedia.org/wiki/ICONIX#ICONIXプロセスの概要 より引用）


# ロバストネス図とは

ロバストネス分析によって分析された結果をロバストネス図によって表現します。具体的には、以下の４種類のオブジェクトを使って、ユースケースを表現します。

* アクター
![icon-Actor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/21efa28f-4374-a9be-60b1-56cb0cd377af.png)
システムと対話をするオブジェクト（人間や外部システム）です。アクターの名前は必ず名詞で表現します。例えば、「一般ユーザー」「社内ユーザー」と名付けます。

* バウンダリ
![icon-Boundary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/981ce80d-a79a-26ef-83fb-a3cdf336f7fd.png)
システムの外部との境界を表現するオブジェクトです。名前は名詞で表現します。アクターが相互作用する画面やボタン、帳票や他システムとのインタフェースなどのソフトウェア要素を表します。例えば、「ログインページ」「申請ページ」のように１つの画面の種類ごとに、１つのバウンダリオブジェクトを定義します。

* エンティティ
![icon-Controller.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/2200b6ce-55ee-df3f-32b8-02a3f57da68d.png)
ドメインモデルを表現するオブジェクトです。名前は名詞で表現します。例えば、「アカウント情報」「申請情報」と名付けます。ソフトウェアシステム内部で半永久的に管理するデータを示します。概念モデルがエンティティオブジェクトの候補となります。そのため、事前に、もしくは、同時並行で概念モデリングを実施します。

* コントローラー
![icon-Entity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/16f4e552-3fd1-dc55-93e9-9186b87384b4.png)
ソフトウェアの機能を表現するオブジェクトです。バウンダリオブジェクトとエンティティオブジェクトをつなぎ、システムが行う処理を定義します。一般的に動詞で表現します。例えば「ID/パスワードをチェックする」「申請情報の入力チェックする」と名付けます。

# ロバストネス図の記載時のルール

ロバストネス図は以下のルールや方針に則って記載します。なお、ルールはいくつか種類がありプロジェクトによって適宜設定されているようです。ここでは代表的なものを示しています。

* 名詞のオブジェクト(バウンダリオブジェクト, エンティティオブジェクト, アクター)同士を直接結んではいけない。コントローラーを介して結ぶこと
* 画面単位でバウンダリオブジェクトを作成する
* 正常系だけでなく異常系のユースケースもロバストネス図で表現する
* ロバストネス分析の途中でもユースケースやドメインオブジェクトを改善する


# ロバストネス図の記述サンプル

ここでは、以下の二つのユースケースを題材にロバストネス図を記載してみます。


|項目|内容|
| :--- | :--- |
|ユースケース名|勤怠情報を入力する|
|アクター|従業員|
|基本フロー| <ul><li>従業員が勤怠管理システムにログインする</li><li>従業員は勤怠情報を登録する</li><li>従業員は勤怠管理システムからログアウトする</li></ul>|
|代替フロー|特になし|

|項目|内容|
| :--- | :--- |
|ユースケース名|従業員の勤怠情報を確認する|
|アクター|管理者|
|基本フロー| <ul><li>管理者が勤怠管理システムにログインする</li><li>管理者は全従業員の勤怠情報を参照する</li><li>管理者は勤怠管理システムからログアウトする</li></ul>|
|代替フロー|特になし|

この二つのユースケースをもとに、ロバストネス図を記述すると以下のようになります。
![RobustnessSample.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/f3dd6c98-3027-1998-64aa-0952d08c9423.jpeg)



---
ここまでが、前半のロバストネス分析の基本中の基本となります。
ここからは、マイクロサービスのサービス分割時にロバストネス分析が有効か否かを考えていきたいと思います。


#マイクロサービスのサービス分割とDDD(ドメイン駆動設計)
システムをマイクロサービス化する時、「サービスをどこで分割していくか」という課題が発生します。割り切りで、「既存の業務に合わせて」とか、「マイクロサービスを適用する目的となった非機能要件を満たせるように分割する」とかなどのやり方でサービス分割していくことはできるかもしれません。しかし、「将来にわたってその切り方で大丈夫なの？」「本当にその切り方であっているの？」など聞かれた場合、なかなか答えづらい状況になってしまうのではないでしょうか。

ここでは、マイクロサービス化の目的が要望・要件の変化に追随していくためである場合について考えます。そして、その目的の場合、DDDの境界づけられたコンテキストでサービスを分けることが有効ではないかと考えます。境界づけられたコンテキストとは統一された言葉（ユビキタス言語）で語ることができる範囲とされています。言葉が違う領域のことを同じ認識でユーザーと開発者が深く会話することや正しく理解することは結構難しいです。領域のことを正しく理解して、変化を正しくつかんでいくためには、この粒度を目指していくことが一つの解ではないかと思います。

境界づけられたコンテキストをまたがって検討しなければならない変化は頻繁に起こらないと考えられます。しかし、境界づけられたコンテキストをまたぐような横断的な変化が起こったとしても、境界づけられたコンテキストが協調して対応することも可能であるため、投資対効果を考慮に入れると、それに備えて分割しないでおくことが有効であることは稀になるのではないでしょうか。

もちろん、将来的にどのような変化が求められるのかをしっかりと予測し関係者間で合意を取って、その結果を基に検討する必要はあるとは思います。

すべての案件でこれで大丈夫だとは言えず適切に適用を判断する必要があるとは思いますが、有力な選択肢の一つになると思います。


#サービス分割時にDDD(ドメイン駆動設計)を活用する時の課題

DDDではドメインエキスパートとの会話によってドメインや境界づけられたコンテキストを明らかにしていきます。しかし、サービス分割時には以下のような課題が挙がってくるとと考えられます。

* ドメインエキスパートとの会話だけではユビキタス言語が網羅的に把握できているか判断することが難しい
* 表面的に表れるものだけでなく、バックオフィスで行われている業務のように内部にあるものも含めて検討する必要がある

これら課題を解決するために、網羅的に会話できたかどうかを担保するためのツール（手段）が求められてきます。

# DDD(ドメイン駆動設計)におけるロバストネス分析の活用

上記で挙げた「サービス分割時にDDD(ドメイン駆動設計)を活用する時の課題」の解決策のひとつとして、ロバストネス分析を活用するという選択肢があるのではないかと考えています。冒頭で「一般的にロバストネス分析は予備設計として詳細設計前に実施されます。」と記載しましたが、ここでは、サービス分割の検討時に活用します。目的が異なるため、記載する内容の粒度感も変わってくると考えます。

エリック・エヴァンスのDDDの中ではロバストネス分析は語られてはいませんでした。しかし、実際の開発では、DDDにおいてもロバストネス分析は活用されるケースがあります。これは、DDDを成功させるためのノウハウとしてロバストネス分析が取り入れられてきたからだと考えられます。先人たちのノウハウをうまく活用しない手はないので、DDDやロバストネス分析等の手法の特徴から、なぜ活用されるのかを考察していきたいと思います。

では、なぜ、DDDにおいてロバストネス分析が活用されるのでしょうか。これは、DDDにおいて重要な概念である境界づけられたコンテキストを定義するために必要な情報を、ロバストネス分析によってより明確にすることができるためだと考えています。DDDでは、ドメインエキスパートとの会話を通して境界づけられたコンテキストを明らかにしていきます。「境界づけられたコンテキストは統一された言葉（ユビキタス言語）で語るができる範囲」なので、対象となるドメイン全体をしっかりと把握する必要があります。ここで、ロバストネス分析を使うことによって、網羅的にドメイン全体が洗い出しができるようになり、結果として、漏れを少なくすることができるのではないでしょうか。

まとめると、サービス分割を考えた場合、ロバストネス分析を活用することには、以下のようなメリットが挙げられると考えられます。

* 境界づけられたコンテキストを定義するためのインプットの精度をあげるため
DDDにおいて境界づけられたコンテキストを定義する時に、そのインプットとなる用語定義やユースケース定義等が十分に検討され洗い出されている必要があります。そこで、ロバストネス分析を用いることによって、ユースケース記述の曖昧なところや不足しているところを明らかにし、境界づけられたコンテキストを定義するために必要な情報を導き出すことができます。

* 境界づけられたコンテキスト間の関係を明らかにするため
ロバストネス分析によって洗い出したオブジェクト間の関連から、境界づけられたコンテキスト間の関係を導き出すことができます。

* 境界づけられたコンテキストを検討する範囲を網羅的に把握するため
ロバストネス分析を行うことによって、ユースケースのようにシステムのインターフェース（表面部分）の動きだけでなく、ユースケースを完遂させるために必要なシステムの機能の洗い出しが可能になります。バックロジックのシステム機能が洗い出されることによって、同一ユースケース内に内包しているドメインや境界づけられたコンテキストの解析が可能となるのではないでしょうか。
![icon-DDD_Robustness.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/38caf62d-83c3-9de7-98c4-fa3db8bbd0e3.png)


#まとめ
マイクロサービスのサービス分割をしたいという要望から課題を洗い出し、それを解決する手法を探ってみた結果、マイクロサービスのサービス分割において、DDDやロバストネス分析を活用していくことは有用であると考えます。

![think_flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519776/1943abe4-79e8-f06a-1c10-e7b2926bdae3.png)

# おわりに
ビジネスやシステムには様々な変化が求められるようになってきています。そして、マイクロサービス化はその様々な変化に対応するための有効な手段のひとつであると認識されるようになってきました。しかし、様々な変化に対応しなければならず、解決すべき課題も多様なので、マイクロサービス化を実現するための採用すべき適切な手段（設計・分析手法）も一つだけではないと考えています。そのため、今後、マイクロサービス化を行おうとする開発者は、要求・要件となる変化に合わせて適切な手段（設計・分析手法）を選択する能力を身に付けていかなければならないのかもしれません。

また、適切な手段であったとしても、目的を見失い使い方を誤れば、期待する結果が得られないばかりか害になることもあります。ロバストネス図でも、記載する粒度やそれぞれの図のまとめ方などは、目的にあわせて調整する必要があると思います。目的を見失わないことも手段であるロバストネス分析を行うときの重要なことだと考えています。



# 参考URL（この記事を作成するために参照したもの）

* [エリック・エヴァンスのドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798121963)
* [実践ドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798131610)
* [「実践ドメイン駆動設計」から学ぶDDDの実装入門](https://www.shoeisha.co.jp/book/detail/9784798161495)
* [ユースケース駆動開発実践ガイド](https://www.shoeisha.co.jp/book/detail/9784798114453)
* [ロバストネス図を活用したシステム設計（Think IT）](https://thinkit.co.jp/article/13487)
* [実践ロバストネス分析（オブジェクトの広場）](https://www.ogis-ri.co.jp/otc/hiroba/technical/RobustnessAnalysis/RA1/)
* [ロバストネス分析の目的（@reoring）](https://qiita.com/reoring/items/d3c5bb9506386404b297)
* [ロバストネス分析について（FREITAGEEK）](https://iikanji.hatenablog.jp/entry/2019/05/19/153809)
* [ロバストネス図は素晴らしい（檜山正幸のキマイラ飼育記 (はてなBlog)）](http://m-hiyama.hatenablog.com/entry/20120618/1339979590)
* [ドメイン駆動設計(DDD)を実践する（システム設計日記）](http://masuda220.jugem.jp/?page=1&cid=13)
* [「実践ドメイン駆動設計」を読んだので、実際にDDDで設計して作ってみた！（@APPLE4869）](https://qiita.com/APPLE4869/items/d210ddc2cb1bfeea9338)