PlantUML で始めるリレーションシップ駆動要件分析 (RDRA)

## はじめに

ソフトウェア開発において、エンジニアが開発対象のドメインの業務に精通していない場合、書く内容やかける時間に程度はあれど **業務分析** や **要件定義** が必要になります。しかし、要件定義の方法論についての話題がネット上に上がることも少なく、書籍などもあまり話題になっていない印象があります (私の観測範囲では)。なので、私の場合、要件定義の実務では公の方法論を体系的に学ばずに、実務で見てきたものを自分なりにアレンジして対応してきました。

そんなとき、モデルベースの要件定義の方法論として **リレーションシップ駆動分析 (RDRA)** というものがあることを知りました。モデリングはずっと取り組んできていることなので、興味が湧いて少し調べてみると [PlantUML](https://plantuml.com/ja/) でも表現できるというではありませんか！

[PlantUML Example for RDRA 2.0 ハンドブック](https://qiita.com/ogomr/items/97058a87337eaa2ba21a)

そこで、[RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX) を購入して読んでみると、それは、理路整然とした要件定義が可能で、エンジニアフレンドリーな **要件定義のフレームワーク** でした。

この記事では、RDRA2.0 を PlantUML で表現する方法と、各図の概要と図 (とその中に含むモデル要素) の間の関連、RDRA2.0 を使うと要件定義がどのようにうれしくなるかなどを紹介したいと思います。

**注意:** この記事は RDRA を網羅的に説明するものではありません。
この記事を読んで、RDRA の方法論を正確に知りたいと思ったり、体系的に学びたいと思った場合は [RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX) を読んでください。

## 要件定義が必要なとき

要件定義はソフトウェアがどうあるべきかという **ソフトウェアの責務** を定義するものです。

明確に区切られた作業としての **要件定義** は今時必要なのでしょうか？アジャイルに分類されるような開発方法の文脈ではあまり話題に上がっていないように感じます。これは、日本でアジャイルの事例としてよく取り上げられているのは、自社で Web サービスを運営しているような現場からの情報発信が多いからではないでしょうか。

Web サービス運営の現場では、ソフトウェアの責務を定義をするのは開発を担当するエンジニアと **同じ部署の人** だったり **同じチームのメンバー** だったりします。なので、提供するサービスであるソフトウェアがどんなものであるべきかを一番良く知っているのは自分たちになります。この場合、要件定義という明確な作業は不要でしょう。

要件定義が必要になるのは、ソフトウェアの責務を定義する人が、他社や自社の別部署など、**開発者の所属と別のところ** である場合です。その場合、プロダクトオーナーやドメインエキスパートの役割を担う人にヒアリングを行い、ソフトウェアの責務となる業務の全体像を把握し、適切な要件を引き出す必要があります。

## 一般的な要件定義書における問題

よくある要件定義書の構成として私が認識しているのは、ざっくり以下のような構成のものです。

- 開発の背景
- 開発の目的
- 要件一覧
- 業務フロー図
- システム構成図
- 機能一覧
- 画面・帳票一覧
- 非機能要件

このような要件定義書はいくつか問題をかかえていると思います。

これらは、一部のダイアグラムを除いて **自然言語** で記述されており、複数人で作成すると分担箇所ごとに文書の体裁や表現に差がでやすいことです。後で校正するとしてもコストがかかります。もし、体裁や表現の違いを放置してしまうと、後から要件定義書を読む人が読み違える可能性があり、その場合は間違って要件が伝わってしまいます。

さらに、自然言語で書く文書を理路整然と表現するのは難しいため **行間を読む** ことが求められることがあります。私も、新入社員のころのプロジェクトで先輩社員から **行間を読め** と指導されたこともります。これも読む人の読解力のようなあいまいなものに依存したものであり、読む人に大きな負担を強いるものです。

他の問題として、これらは複数の文書で1つの要件定義書となりますが、ある一つの項目が複数の文書に分散して記載されることがあります。ここで問題なのは、文書間や文書内の内容の間の **関連が明確に紐付けられていない** ため、ある項目について把握しようとしたときに読み漏らしてしまう可能性があります。また、複数箇所に分散されている記載内容の整合性を維持するのも大変です。

## 解決策: リレーションシップ駆動要件分析 (RDRA)

RDRA では、**決められたアイコンを使い**、**アイコンとアイコン、アイコンと図** を関連としてつなぐことで、アイコンで表現された **モデル要素** と **関連** のつながりから要件を説明します。

RDRA では以下の種類の図が定義されており、これらを全て使用して基本的には図のみで要件を定義します。

- システムコンテキスト図
- 要求モデル図
- ビジネスコンテキスト図
- ビジネスユースケース図
- 業務フロー図
- 利用シーン図
- バリエーション・条件図
- ユースケース複合図
  - + 業務フロー図
  - + 利用シーン図
- 情報モデル図
- 状態モデル図

UML に非常によく似ていますが、違いとしては UML ほどアイコンの使いかたに厳密ではなく、図をまたいで共通のアイコンを使います。また、アイコン単位にブレイクダウンしてアイコンの詳細を説明するための図を定義しており、全ての図を通して **アイコンとアイコン** または **アイコンと図** が全てつながるようなルールとなっています。そのため、RDRA はトレーサビリティを持ちます。

**RDRA のイメージ:** ※この図は全体像を想像しやすくするために書いた概念図です。厳密さはありません。
![全体像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/b8b71d79-98f5-f6eb-2486-73f94ce7c6d0.png)

図やアイコンが繋がることにより、関連をたどることで全図を通しての妥当性がチェック可能になり、要件の検討漏れの検証、整合性の保証が可能になります。また、開発が進んで仕様変更が発生した場合にも、関連をたどることで漏れ無く影響範囲を洗い出すことができます。なので、実装を要件定義書にフィードバックすることも容易です。

## RDRA をするときにも採用したい PlantUML

[PlantUML](https://plantuml.com/ja/) は、テキストファイルとして書かれた Markdown から HTML がレンダリング可能なように、[PlantUML](https://plantuml.com/ja/) で定義された記法に沿って書かれたテキストファイルから様々なダイアグラムをレンダリングすることが可能なモデリングツールです。
UML はもちろん他にも、ER図、マインドマップ、WBS なども書けます。

テキストファイルで書けることの一般的なメリットとして、Git で管理することが容易で、差分を簡単に確認できることなどがあります。GitHub のようなソースコード管理ツール上でのレビューで行を指定してコメントをすることもできます。

パーサーを書けば、モデル要素の一覧表示、モデル要素から関連をたどるツール、関連のバリデーション、入力補助ツールなど、いろいろな便利ツールを用意することも可能です。

## PlantUML で RDRA の図を書くときのアイコン

[RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX) で紹介されているアイコンを PlantUML で書く場合のアイコンを対応付けすると以下のようになります。
※一部のみ掲載。

| RDRA2.0 ハンドブック | PlantUML | 登場する図 |
| --- | --- | --- |
| アクター | ![アクター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/23de7d65-8cc7-3129-37d0-4f539c1bf910.png) | システムコンテキスト図、要求モデル図、ビジネスコンテキスト図、ビジネスユースケース図、利用シーン図、ユースケース複合図 |
| システム | ![システム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/b46a29e3-d368-7c82-b119-c852cb98291f.png) | システムコンテキスト図 |
| 外部システム | ![外部システム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/2790c5e1-7443-fc48-6e0f-906b981b07b2.png) | システムコンテキスト図 |
| 要求 | ![要求.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/85e4acfb-e624-25a3-d86d-b71171989db6.png) | 要求モデル図 |
| 業務 | ![業務.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/9cce6984-d777-5e4b-50f5-7a3b7caa370b.png) | ビジネスコンテキスト図 |
| ビジネス要素 | ![ビジネス要素.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/176c8b8b-a276-0eb2-9370-68b76cf7cb11.png) | ビジネスコンテキスト図、ビジネスユースケース図 |
| ビジネスユースケース | ![ビジネスユースケース.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/e13a19d7-b1e5-5640-6b14-3645f1242cc8.png) | ビジネスユースケース図 |
| アクティビティ | ![アクティビティ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/9316cde9-4c05-be2b-3427-722284a12e57.png) | 業務フロー図、ユースケース複合図 |
| 利用シーン | ![利用シーン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/1402f061-907d-b2a2-0a55-db6d0ec1c6e3.png) | 利用シーン図、ユースケース複合図 |
| ユースケース | ![ユースケース.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/3498c6d9-c654-469b-7c57-52b24cca5240.png) | 業務フロー図、利用シーン図、ユースケース複合図 |
| 画面 | ![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/39a24a44-d36c-c40b-73b3-c9501f9f2a9b.png) | ユースケース複合図 |
| 情報 | ![情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/20be537a-c829-8aff-a994-c1150835c8eb.png) | ユースケース複合図、情報モデル図 |
| イベント | ![イベント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/a9c0f316-ea94-b544-0b7a-518ff1711b29.png) | ユースケース複合図 |
| バリエーション | - | - |
| 条件 | ![条件.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/1e2f8bea-f79a-608e-7a5f-533b8e57213f.png) | ユースケース複合図 |

## RDRA 図のサンプル

**RDRA2.0 ハンドブック** で登場する図を PlantUML で記述してみました。
各図の目的と説明、PlantUML ではどのアイコンを使用するのかについて簡単に説明します。

### システムコンテキスト図

システムに関わる人や外部システムを把握するためのものです。
要件定義が進んできたら **システム化の目的** を簡潔にまとめます。これはシステム化のテーマのようなものです。
要件定義の中で新たな **アクター** が発見されたらこの図にも追加します。

**アクター** は `actor` で表現します。
**システム** は `usecase` で表現します。
**外部システム** は `agent` で表現します。
**システム化の目的** は `note` で表現します。

![10.02.システムコンテキスト図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/72ef8d77-1620-b713-e599-fd4aba26ff84.png)

```
@startuml

title システムコンテキスト図

left to right direction

actor 会員
actor 図書館員

agent 書籍通販会社

usecase 図書館システム
note top of 図書館システム
  図書館員の作業 (書籍購買の自動連携) を支援し、本の貸
  出・返却業務において会員を待たせないスムーズな運用を
  実現する。蔵書管理をリアルタイムで行い、検索、在庫な
  ど会員サービスを向上させる
end note

:会員: -- (図書館システム)
:図書館員: -- (図書館システム)
(図書館システム) -- 書籍通販会社

@enduml
```

### 要求モデル図

システム開発にあたり顧客からの要求一覧などがあると思います。それを整理して **要求** を洗い出します。
**要求** はその価値を **直接受け取る** `actor` と関連付けます。ここで登場する `actor` が **システムコンテキスト図** に存在しないようであればそちらにも追加します。
細かい機能要件は設計に入ってから考慮するので、ここでは除外します。また、課題などは要求の形に換えます。
要件定義を進めていくなかで **要件** を **〜できること** の表現にして整理します。

**要求**、**要件** は `note` で表現します。

![10.03.要求モデル図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/3871e5d1-1603-9225-70fe-4abaa7952928.png)

```
@startuml

title 要求モデル図

left to right direction

actor 司書
note "本の購入を簡素化したい" as s_r1
note "返却率が悪くならないように返却を簡単にする" as s_r2
note as s_dr1 #Turquoise
  本の購入を Web で直接行え、購入した本の情
  報をそのままシステムに取り込めること
end note
:司書: -- s_r1
:司書: -- s_r2
s_r1 -- s_dr1
s_r2 -- s_dr1

actor 図書館員
note "本の貸出、返却手続きを簡素化したい" as t_r1
note "本の在庫をリアルタイムで把握したい" as t_r2
note as t_dr1 #Turquoise
  本の貸出と返却を簡易に行え、リアルタ
  イムで在庫に反映できること
end note
:図書館員: -- t_r1
:図書館員: -- t_r2
t_r1 -- t_dr1
t_r2 -- t_dr1

actor 会員
note "見たい本が図書館にあるかを Web で検索したい" as k_r1
note "借りたい本を Web で予約したい" as k_r2
note as k_dr1 #Turquoise
  Web で借りたい本を検索でき、
  そのまま予約できること
end note
:会員: -- k_r1
:会員: -- k_r2
k_r1 -- k_dr1
k_r2 -- k_dr1

@enduml

```

### ビジネスコンテキスト図

システム化対象の業務全体を高い抽象度で表現した図です。
大きなレベルでの **業務** を洗い出し、その業務に携わる **アクター** や、**組織** と関連付けます。
また、その業務で取り扱う **ビジネス要素** も **業務** と関連付けます。

**業務** は `usecase` で表現します。
**ビジネス要素** のうち **会社** は `node`、**組織** は `agent` や `rectangle`、その他は `artifact`、`card`、`file` などで表現します。

![10.01.ビジネスコンテキスト図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/9a057318-aced-3cad-974b-950d511aee2d.png)

```
@startuml

title ビジネスコンテキスト図

left to right direction

actor 会員

node 図書館 {
  rectangle 窓口 {
    actor 図書館員
  }
  rectangle 司書室 {
    actor 司書
  }
  usecase 会員管理
  usecase 貸出返却
  usecase 蔵書管理
  artifact 蔵書
  artifact 書架
}

node 書籍店

:会員: -- (会員管理)
(会員管理) -- :図書館員:

:会員: -- (貸出返却)
(貸出返却) -- :図書館員:
(貸出返却) -- 蔵書
(貸出返却) -- 書架

蔵書 -- (蔵書管理)
書架 -- (蔵書管理)
(蔵書管理) - :司書:
(蔵書管理) -- 書籍店

@enduml
```

### ビジネスユースケース図

**ビジネスコンテキスト図** の **業務** 1つが、1つの **ビジネスユースケース図** になります。
**業務** を **ビジネスユースケース** に細分化して、関わる **アクター** や **ビジネス要素** と関連付けます。
この図を作っていく中で、見つけた **アクター** や **ビジネス要素** などは上位の図にそれぞれフィードバックして反映します。

**ビジネスユースケース** は `usecase` として表現します。
※他のアイコンは **ビジネスコンテキスト図** と同じです。

![10.05.ビジネスユースケース図_貸出・返却.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/406c8a12-a1d9-9c70-a884-e353ab81f425.png)

```
@startuml

title ビジネスユースケース図 - 貸出・返却:業務

left to right direction

actor 会員
actor 図書館員

agent 窓口

usecase 窓口貸出
usecase Web予約
usecase 返却

artifact 蔵書
artifact 書架

:図書館員: -- (窓口貸出)
(窓口貸出) -- 窓口
(窓口貸出) -- 蔵書
(窓口貸出) -- 書架

:会員: -- (Web予約)
:図書館員: -- (Web予約)
(Web予約) -- 蔵書
(Web予約) -- 書架

:図書館員: -- (返却)
(返却) -- 窓口
(返却) -- 蔵書
(返却) -- 書架

@enduml
```

### 業務フロー図

**ビジネスユースケース図** の1つの **ビジネスユースケース** が1つの **業務フロー図** (または、利用シーン図のどちらか) になります。**ビジネスユースケース** の具体的なワークフローを表現します。また、それぞれの **アクティビティ** でシステムが関連する場合には **ユースケース** と関連付けます。

この図を PlantUML のアクティビティ図で表現しましたが全然満足できるようなものにはなりませんでした。業務フロー図単体ではなく、**ユースケース複合図 + 業務フロー** で表現したほうがいいかもしれません。

**アクター** は **スイムレーン** `||` で表現します。
**アクティビティ** は `partition` で **フレーム** として表現してみました。**ユースケース** をパッケージにまとめた作業というような意味のつもりです。
**ユースケース** は `:;` で表現します。

![05.06.業務フロー図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/f7fe03cd-ed8b-e9df-2b15-8b08e72006d0.png)

```
@startuml

title 業務フロー図 - Web予約:BUC

/'
actor 会員
actor 図書館員
usecase 貸出本の予約・取消をする
usecase 予約図書一覧を出力する
usecase 予約図書を取り置く
usecase 取置図書を消しこむ
'/

|会員|
partition 貸出予約 {
  :貸出本の予約・取消をする;
}

|図書館員|
partition 予約図書の準備 {
  :予約図書一覧を出力する;
  split
    :予約図書を取り置く;
  split again
    -> 貸出図書が無い場合;
    stop
  end split
}

|会員|
partition 予約図書を受け取る {
  :取置図書を消しこむ;
}
stop

@enduml
```

### 利用シーン図

**ビジネスユースケース図** の1つの **ビジネスユースケース** が1つの **利用シーン図** (または、業務フロー図のどちらか) になります。**ビジネスユースケース** をワークフロー (業務の流れ) として表現できない場合に使用します。
**利用シーン** でシステムを使うメリットや解決する課題を **シナリオ** (または箇条書き) として記述します。
**利用シーン** と **アクター** を関連付けます。**利用シーン** がシステムと関わる場合には、**ユースケース** と関連付けます。

**利用シーン** は **業務フロー図** の **アクティビティ** と合わせるために `frame` で表現しました。
**ユースケース** は `usecase` で表現します。
**シナリオ** は `note` で表現します。

![10.13.利用シーン図_会員登録.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/1a53ea4c-2502-9feb-4497-feb335b1b100.png)

```
@startuml

title 利用シーン図 - 会員登録:BUC

left to right direction

actor 会員
actor 図書館員

frame 会員登録
note right of 会員登録
  本の貸出・返却時の単純化のために事前に会員登録を行う
  既に図書カードを導入しているが、忘れる人が多いので図書カード以外での確認方法も欲しい
  新しい機器を持たない老人もいるので図書カードもそのまま残したい
  会員登録も利用者本人ができるようにしたい
end note

frame 会員の確認
note right of 会員の確認
  本 (電子図書含む) の貸出の時の会員認証を簡単に行いたい
  図書カード等を忘れた場合にも口頭で対応できるようにしたい
end note

usecase 会員IDを発行する
usecase 会員カードを作成する
usecase 会員を特定する

:会員: -- 会員登録
:図書館員: -- 会員登録
会員登録 -- (会員IDを発行する)
会員登録 -- (会員カードを作成する)

:図書館員: -- 会員の確認
会員の確認 -- (会員を特定する)

@enduml
```

### バリエーション・条件図

**バリエーション・条件図** は図とありますが、実体は表形式で表現します。
**バリエーション** はビジネス上に登場する値であり、重要なビジネスルールの基準になるような情報です。
**条件** は単純なものは **名前つけられた条件** としてまとめ、**バリエーション** の組み合わせで条件が決まるものは **条件** ごとに表形式で表現します。
表形式なので Markdown のテーブルやスプレッドシートなどで作成して、それを実体とします。
**ユースケース複合図** で参照するときは、エイリアスを `control` のアイコンで表現して関連付けます。

**バリエーション**

| 本種別|
| --- |
| 書籍 |
| 館内閲覧用専用書籍 |
| DVD |
| CD |

| 遅延日数 |
| --- |
| 遅延日数 < 3日 |
| 遅延日数 < 7日 |
| 上記以外 |

| 会員種別 |
| --- |
| 大人 |
| 子供 |

**名前つけられた式**

| 名前 | 式 |
| --- | --- |
| 貸出期限 | 貸出日 + 14日 |
| 取置期限 | 貸出準備完了日 + 7日 |

**条件**

2軸の組み合わせであれば以下のような表になります。

**貸出制限:条件**

| **遅延日数**\\**会員種別** | 大人 | 子供 |
| --- | --- | --- |
| 遅延日数 < 3日 | 1人5冊まで | 1人7冊まで |
| 遅延日数 < 7日 | 本の貸し出し不可 | 1人4冊まで |
| 上記以外 | 本の貸し出し不可 | 本の貸し出し不可 |

or

こんな感じのマトリックスであれば3軸以上の組み合わせでも表現可能ですね。

**貸出制限:条件**

|  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- |
| **遅延日数**<br> < 3日 | o | o | x | x | x | x |
| < 7日 | x | x | o | o | x | x |
| 上記以外 | x | x | x | x | o | o |
| **会員種別**<br>大人 | o | x | o | x | o | x |
| 子供 | x | o | x | o | x | o |
|---|---|---|---|---|---|---|
| **貸出制限** | 1人5冊まで | 1人7冊まで | 本の貸し出し不可 | 1人4冊まで | 本の貸し出し不可 | 本の貸し出し不可 |

### ユースケース複合図

**ビジネスユースケース図** の **ビジネスユースケース** 単位で作成すると見通しがよくなります。
**ユースケース** を中心に、**画面**、**情報**、**条件**、**イベント** を関連付けます。
**画面** はユーザーから何らかの入力や、何かの出力 (帳票などを含む) が必要であることを示します。それが実装上の1つの画面になるわけではなく、概念的な入力の単位になります。
**情報** は **情報モデル図** に登場する **情報** です。そのユースケースによって操作される情報を示します。
**条件** は **バリエーション・条件図** の **条件** へのエイリアスです。**ユースケース** の処理で適用される **条件** を示します。
**イベント** は **外部システム** との連携 (IN/OUT) があることを示します。**外部システム** は **システムコンテキスト図** で登場しているはずです。

**画面** は `boundary` で表現します。
**情報** は `entity` で表現します。
**条件** は `control` で表現してみました。**条件** は実装上はビジネスロジックとしての処理に近いはずです。`control` はロバストネス図で処理を表します。
**イベント** は `interface` で表現してみました。**外部システム** とは Web API などの **インターフェース** を介してやりとりされるはずなので、このアイコンを採用してみました。

![05.09.ユースケース(UC)複合図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/80404694-ffd4-292d-98cc-8c03ac7155f6.png)

```
@startuml

title ユースケース複合図 - Web予約:BUC

left to right direction

actor 会員

entity 貸出予約
entity 蔵書

usecase 予約図書一覧を出力する
boundary 貸出予約一覧
control 貸出予約一覧出力条件

貸出予約一覧 - (予約図書一覧を出力する)
貸出予約一覧 -- 貸出予約一覧出力条件
(予約図書一覧を出力する) -- 貸出予約

usecase 予約図書を取り置く
boundary 貸出準備登録
control 取置期限
interface 貸出可能を通知する
control 予約貸出通知メッセージ

貸出準備登録 - (予約図書を取り置く)
(予約図書を取り置く) - 取置期限
(予約図書を取り置く) -- 貸出予約
(予約図書を取り置く) -- 蔵書
(予約図書を取り置く) -- 貸出可能を通知する
予約貸出通知メッセージ - 貸出可能を通知する
貸出可能を通知する -- 会員

@enduml
```

### ユースケース複合図 + 業務フロー

**業務フロー図** と **ユースケース複合図** を1つの図としてまとめたものです。
業務フローと一緒にシステムとのやりとりの全体像が把握できるので、**ビジネスユースケース** の規模が小さく図が複雑にならない場合はこちらのほうがよさそうです。図が複雑になる場合、PlantUML ではレンダリング結果が意図しないものになる可能性が高く、調整もあまりできないので、図を分割したほうがいいです。

![10.11.ユースケース複合図_Web予約.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/24dc9d1b-2142-cb69-d576-3690b2447f96.png)

```
@startuml

title ユースケース複合図 - Web予約:BUC

left to right direction

actor 会員
actor 会員 as a会員
actor 図書館員

frame 貸出予約 as f貸出予約
frame 予約図書の準備 as f予約図書の準備
note bottom of f予約図書の準備
・貸出予約一覧を出力
・未取り置きのものを探す
・取置棚に置く
end note
frame 予約図書を受け取る as f予約図書を受け取る

usecase "貸出本の予約・取消をする"
usecase 予約図書一覧を出力する
usecase 予約図書を取り置く
usecase 予約図書を消しこむ
usecase 蔵書の貸出を登録する

boundary 蔵書検索 as b蔵書検索
boundary 貸出予約 as b貸出予約
boundary 貸出予約一覧 as b貸出予約一覧
boundary 貸出準備登録 as b貸出準備登録
boundary 予約消込 as b予約消込

control 貸出予約一覧出力条件 as c貸出予約一覧出力条件
control 取置期限 as c取置期限
control 予約貸出通知メッセージ as c予約貸出通知メッセージ

entity 貸出予約 as e貸出予約
entity 蔵書 as e蔵書

interface 貸出可能を通知する as i貸出可能を通知する

:会員: -- f貸出予約
f貸出予約 -- (貸出本の予約・取消をする)
b蔵書検索 - (貸出本の予約・取消をする)
b貸出予約 - (貸出本の予約・取消をする)
(貸出本の予約・取消をする) -- e蔵書
(貸出本の予約・取消をする) -- e貸出予約

f貸出予約 -> f予約図書の準備

:図書館員: -- f予約図書の準備
c貸出予約一覧出力条件 - b貸出予約一覧
b貸出予約一覧 - (予約図書一覧を出力する)
f予約図書の準備 -- (予約図書一覧を出力する)
(予約図書一覧を出力する) -- e貸出予約

f予約図書の準備 -- (予約図書を取り置く)
b貸出準備登録 - (予約図書を取り置く)
(予約図書を取り置く) - c取置期限
(予約図書を取り置く) -- e貸出予約
(予約図書を取り置く) -- e蔵書
(予約図書を取り置く) -- i貸出可能を通知する
c予約貸出通知メッセージ - i貸出可能を通知する
i貸出可能を通知する -- :a会員:

f予約図書の準備 -> f予約図書を受け取る

:会員: -- f予約図書を受け取る
:図書館員: -- f予約図書を受け取る
f予約図書を受け取る -- (予約図書を消しこむ)
(予約図書を消しこむ) - (蔵書の貸出を登録する)
b予約消込 - (予約図書を消しこむ)
(予約図書を消しこむ) -- e貸出予約

@enduml
```

### ユースケース複合図 + 利用シーン

**利用シーン図** と **ユースケース複合図** を1つの図としてまとめたものです。

![10.14.ユースケース複合図_期限管理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/36c4d854-c44d-66d4-6360-9b0e4077f74d.png)

```
@startuml

title ユースケース複合図 - 期限管理:BUC

left to right direction

actor 会員
actor 図書館員
actor 日時<<タイマー>>

frame 取置図書の返却
note bottom of 取置図書の返却
  取り置き期限切れのものを書架に戻す
end note

usecase 貸出期限を確認する
usecase 取置期限を確認する

boundary 取置期限切れ as b取置期限切れ

entity 貸出図書
entity 貸出予約
entity 取置期限切れ

interface 貸出期限切れ通知
interface 取置期限切れ通知

:日時: -- (貸出期限を確認する)
(貸出期限を確認する) -- 貸出図書
(貸出期限を確認する) -- 貸出期限切れ通知
貸出期限切れ通知 -- :会員:

:日時: -- (取置期限を確認する)
(取置期限を確認する) -- 貸出予約
(取置期限を確認する) -- 取置期限切れ通知
取置期限切れ通知 -- :会員:
(取置期限を確認する) - 取置期限切れ

:図書館員: -- 取置図書の返却
取置図書の返却 -- (取置期限を確認する)
b取置期限切れ - (取置期限を確認する)

@enduml
```

### 情報モデル図

**ユースケース図** で登場した **情報** が全てここにあるはずです。
**情報** 同士を適切に関連付けます。概念モデルのようなものです。

**情報** は `entity` で表現します。

![10.07.情報モデル図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/4e78a4ab-749b-c197-5dd2-2653453026f8.png)

```
@startuml

title 情報モデル図

left to right direction

entity 会員

entity 本
entity 蔵書
entity 書架

entity 貸出予約
entity 貸出図書

entity 書籍発注

会員 -- 貸出予約
貸出予約 -- 本

会員 -- 貸出図書
貸出図書 -- 本

本 - 蔵書
蔵書 - 書架

本 -- 書籍発注

@enduml
```

### 状態モデル図

**情報** の取り得る **状態** と、どの **ユースケース** によって **状態** が遷移するかを表現しています。

**ユースケース** はイベントとして `(ユースケース名)` のように表記します。
1つのユースケースの中で **条件** によって遷移先の **状態** を切り替える場合は、イベントの2行目に `[条件]` のように表記します。(例. `(貸出期限を確認する)\n[貸出期限 >= 今日]`)

![10.08.状態モデル図_Web予約.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85728/2a9bfb68-02c3-6bb3-47a2-3218bf55536b.png)

```
@startuml

title 状態モデル図 - Web予約:情報

/'
usecase 貸出本を予約する
usecase 貸出本を予約取消する
usecase 予約図書を取り置く
usecase 取置期限を確認する
usecase 取置図書を消しこむ
'/

state 未予約

state 予約中 {
  state 未準備
  state 準備完了
}

[*] --> 未予約
未予約 --> [*]

未予約 --> 未準備: (貸出本を予約する)
予約中 --> 未予約: (貸出本を予約取消する)

未準備 --> 準備完了: (予約図書を取り置く)

準備完了 --> 準備完了: (取置期限を確認する)\n[取置期限 >= 今]
準備完了 --> 未予約: (取置期限を確認する)\n[取置期限 < 今]

準備完了 --> 未予約: (取置図書を消しこむ)

@enduml
```

## 実際に要件をヒアリングしながら RDRA で作図するとき

PlantUML は複雑な図を書くのは大変そうだなと感じていたのであまり使ってこなかったですが、RDRA では図の分割単位がルール化されていてそれに従うと自然にある程度小さな図に分割されるため、PlantUML でもあまり複雑にならなそうな気がしています。
ただし、プロダクトオーナーやドメインエキスパートの人たちとミーティングの中でさくさく作図していくのは難しそうです。PlantUML 力が上がれば可能なんでしょうかね？
もし、やるとしたら、前回のミーティングまでの成果を PlantUML で作図して、事前に画像 or 紙に印刷して事前配布しておいて、それを参照しながら、今回のミーティングの議題部分はホワイトボードに書きながらすりあわせるような感じでしょうか？

もし、1つのスクリーンを全員で共有して、ミーティングしながら並行して作図していくのであれば [astah*](http://astah.change-vision.com/ja/) を使うとよさそうです。astah* UML でもできそうですが、アイコンを柔軟に替えられたり、モデルに別名をつけれたりするので、astah* Professional のほうがよさそうです。

## その後の開発

### 概算工数の見積もり

RDRA で図が完成した時、要件を満たすのに必要な **ユースケース** が全て洗いだされているはずです。
また、それぞれの **ユースケース** の概要は **ユースケース複合図** に、入出力 (**画面**)、複雑さ (**条件**)、外部システム連携 (**イベント**)、扱う情報 (**情報**) として漏れなく表現されているので、概算工数を見積もることが可能です。また、**情報モデル図** や **状態モデル図** も複雑さを判断するのに役立ちます。

### DDD

要件の把握ができ、設計としてのモデリングを開始するときは、合意が取れている **情報モデル図**、**状態モデル図** があることで、スタートをスムーズに切ることが可能です。
この後は、ドメインエキスパートと一緒にモデルを洗練させていきます。その中で、新しい学びにより、RDRA モデルへのフィードバックが必要になるかも知れません。ただし、設計モデルをそのまま RDRA モデルへ反映すると、要件を確認するときの粒度としては不適切になる可能性があるため、反映の粒度は適切に判断する必要があります。

### 開発手法

ウォーターフォールでも、チケット駆動開発でも、スクラムのバックログでも、ユーザーストーリーマッピングを使うでも、どんな開発手法でも効果的に開発を始められると思います。
例えばユーザーストーリー単位に開発している場合でも、最初から扱うことになるビジネスモデル全体が (洗練されていないとしても) 把握できることによって、今の実装 (モデル) がこの次にどのような構造になるかを予測することができるので、間違った解釈で実装して後から大きなリファクタリングが必要になる頻度も減るかもしれません。

## まとめ

RDRA は要件を論理的に定義できて、妥当性や網羅性もチェックできるため、エンジニアにとっても好感を持てる要件定義手法ではないでしょうか？
注意点として RDRA では非機能要件は扱いません。こちらも重要なので忘れないようにしましょう。

この記事では、[RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX) を読んだ直後の私の理解をまとめ、ついでに [PlantUML](https://plantuml.com/ja/) でやってみようと思って実践したもので、RDRA の本来の価値を伝える情報としては大きく不足していると思います。正確性にも欠ける部分があるかもしれません。
やはり、常に原典を当たるのが最短で最適だと思うので、当記事を読んで興味が湧いた方は [RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX) を読むことをおすすめします。

## 参考文献

- [PlantUML Example for RDRA 2.0 ハンドブック](https://qiita.com/ogomr/items/97058a87337eaa2ba21a)
- [RDRA2.0 ハンドブック](https://www.amazon.co.jp/RDRA2-0-ハンドブック-軽く柔軟で精度の高い要件定義のモデリング手法-神崎善司-ebook/dp/B07STQZFBX)
- [PlantUML](https://plantuml.com/ja/)