PlantUML Example for モデルベース要件定義テクニック

[PlantUML](http://plantuml.com/)はテキストの記述で[UML](https://en.wikipedia.org/wiki/Unified_Modeling_Language)の図を描くことができます。オプション機能や組み合わせで色々な表現をすることができるので、UML を拡張した図が使われる[モデルベース要件定義テクニック](https://www.shuwasystem.co.jp/book/9784798039442.html)の書籍からいくつかのモデルを記述します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8369/cb094dfc-bcef-0a02-07b5-c59a3df1f671.png)
書籍にはモデルの着眼点や解説が丁寧に記載されています。図の背景に興味がある方は合わせてお読みください。

---

## コンテキストモデル

- [ユースケース図](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#use-case)でシステムの関係者を整理します。
- `left to right direction` を利用すると図の方向を左から右に変更できます。

```
left to right direction

actor 経営者

rectangle システムに直接関わる人 {
  actor 顧客
  actor 営業
  actor 物流
  actor システム部門
  actor オーダー部門
  経営者 -- 営業
  経営者 -- 物流
  顧客 -- (商品販売サイト)
  営業 -- (商品販売サイト)
  物流 -- (商品販売サイト)
  システム部門 -- (商品販売サイト)
  オーダー部門 -- (商品販売サイト)
  (商品販売サイト) .. [出荷システム]
  (商品販売サイト) .. [入荷システム]
  (商品販売サイト) .. [決済システム]
}
```

```plantuml
left to right direction

actor 経営者

rectangle システムに直接関わる人 {
  actor 顧客
  actor 営業
  actor 物流
  actor システム部門
  actor オーダー部門
  経営者 -- 営業
  経営者 -- 物流
  顧客 -- (商品販売サイト)
  営業 -- (商品販売サイト)
  物流 -- (商品販売サイト)
  システム部門 -- (商品販売サイト)
  オーダー部門 -- (商品販売サイト)
  (商品販売サイト) .. [出荷システム]
  (商品販売サイト) .. [入荷システム]
  (商品販売サイト) .. [決済システム]
}
```

---

## 要件モデル

- [要素](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#element)にノートを記載して要求を整理します。
- `end note` を利用するとノートで改行が使えます。

```PlantUML
left to right direction

actor システム部門
actor 物流
actor 経営者
actor 営業

actor 営業
note right : 営業としてオーダーそのものは顧客に直接ウェブブラウザから入力して欲しいと願っている
actor 営業
note right : 営業はオーダー作業よりもより分析的な仕事にシフトしたいと考えている
actor 営業
note right : 商品の特性と売れた時期、売れた場所を管理したいと考えている
actor 営業
note right : 売れた時期は月単位で管理したい
actor 営業
note right : 売れた場所は関東圏を中心に直感的に理解できるようにマップ上に売れた商品を表示して欲しい
actor 営業
note right : 多様な顧客のニーズに沿えるように入金手段はなるべくいろいろなものを利用したいと考えている

actor 経営者
note right
  営業にはオーダー作業よりもより戦略的な商品管理の仕事にシフトしてもらいたいと考えている。
  オーダー処理そのものは新たにオーダー部門を用意してそこに集約する
end note

actor 物流
note right : 物流は既存の入庫、出庫システムとの連動を望んでいる

actor システム部門
note right : システム部門は今後の保守と考え使用する技術は統一したいと考えている
```

```plantuml
left to right direction

actor システム部門
actor 物流
actor 経営者
actor 営業

actor 営業
note right : 営業としてオーダーそのものは顧客に直接ウェブブラウザから入力して欲しいと願っている
actor 営業
note right : 営業はオーダー作業よりもより分析的な仕事にシフトしたいと考えている
actor 営業
note right : 商品の特性と売れた時期、売れた場所を管理したいと考えている
actor 営業
note right : 売れた時期は月単位で管理したい
actor 営業
note right : 売れた場所は関東圏を中心に直感的に理解できるようにマップ上に売れた商品を表示して欲しい
actor 営業
note right : 多様な顧客のニーズに沿えるように入金手段はなるべくいろいろなものを利用したいと考えている

actor 経営者
note right
  営業にはオーダー作業よりもより戦略的な商品管理の仕事にシフトしてもらいたいと考えている。
  オーダー処理そのものは新たにオーダー部門を用意してそこに集約する
end note

actor 物流
note right : 物流は既存の入庫、出庫システムとの連動を望んでいる

actor システム部門
note right : システム部門は今後の保守と考え使用する技術は統一したいと考えている
```

---

## 業務モデル

- [アクティビティ図](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#activity)で業務の流れを整理します。

### 商品管理業務

- アクターが使えないので `<&person>` を利用して :bust_in_silhouette: のアイコンで代用します。
  - 他にも [Open Iconic](https://useiconic.com/open/) のアイコンが利用できます。

```
start
:商品販売状況を確認する;
note right : <&person> 営業:
:商品情報を登録・変更する;
note right : <&person> 営業:
stop
```

```plantuml
start
:商品販売状況を確認する;
note right : <&person> 営業:
:商品情報を登録・変更する;
note right : <&person> 営業:
stop
```

### 入荷業務

- `note left` でノートの位置を変更することができます。

```
start
:発注処理;
note left : <&person> 営業:新規商品の発注
:入荷商品の確認;
note left : <&person> 物流:在庫切れ、在庫補充の発注
:入荷処理;
note left : <&person> 物流:
stop
```

```plantuml
start
:発注処理;
note left : <&person> 営業:新規商品の発注
:入荷商品の確認;
note left : <&person> 物流:在庫切れ、在庫補充の発注
:入荷処理;
note left : <&person> 物流:
stop
```

### オーダー業務

- `|`（パイプ） を利用してアクティビティを分割します。(swimlane)
- `fork` を利用して並列処理を記述します。

```
|顧客|
start
:商品購入;
fork
  :メール確認;
  :支払い;
|オーダー担当|
fork again
  :オーダー確認;
  :入金確認;
endfork
while (入金額の差違) is (入金額と請求額に差違がある)
  :入金の差違の解消;
  if (オーダー接続) then (キャンセル)
    :オーダー取り消し;
    stop
  else (キャンセルしない)
  endif
endwhile (入金額と請求額が一致する)
:出荷指示;
fork
|顧客|
:オーダー状況の確認;
fork again
  |物流|
  :出荷業務;
  :出荷完了指示;
  |オーダー担当|
  :配達完了メール通知待ち;
  :オーダー完了登録;
endfork
stop
```

```plantuml
|顧客|
start
:商品購入;
fork
  :メール確認;
  :支払い;
|オーダー担当|
fork again
  :オーダー確認;
  :入金確認;
endfork
while (入金額の差違) is (入金額と請求額に差違がある)
  :入金の差違の解消;
  if (オーダー接続) then (キャンセル)
    :オーダー取り消し;
    stop
  else (キャンセルしない)
  endif
endwhile (入金額と請求額が一致する)
:出荷指示;
fork
|顧客|
:オーダー状況の確認;
fork again
  |物流|
  :出荷業務;
  :出荷完了指示;
  |オーダー担当|
  :配達完了メール通知待ち;
  :オーダー完了登録;
endfork
stop
```

---

## 概念モデル

- [オブジェクト図](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#object)で概念を整理します。
- `."*"` を利用して多重度を記述します。

```
object 顧客
object 販売商品
object パッケージ商品
object 仕入れ商品
object 取引先

顧客 ."*" 販売商品 : 販売する
販売商品 "*"..o パッケージ商品
販売商品 <|.. パッケージ商品
販売商品 <|.. 仕入れ商品

仕入れ商品 "*"..o 取引先 : 仕入れる
```

```plantuml
object 顧客
object 販売商品
object パッケージ商品
object 仕入れ商品
object 取引先

顧客 ."*" 販売商品 : 販売する
販売商品 "*"..o パッケージ商品
販売商品 <|.. パッケージ商品
販売商品 <|.. 仕入れ商品

仕入れ商品 "*"..o 取引先 : 仕入れる
```

---

## ユースケースモデル

- [ユースケース図](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#use-case)でユーザーとシステムの接点を整理します。
- `usecase ... as` を利用して説明を記述します。

```
left to right direction

actor 営業
actor 物流
actor 顧客
actor オーダー部門

usecase 商品を発注する as "<<入荷システム>>
--
商品を発注する"
営業 -> 商品を発注する
商品を発注する <- 物流

usecase 入荷商品を登録する as "<<入荷システム>>
--
入荷商品を登録する"
物流 -> 入荷商品を登録する

usecase 出荷を完了する as "<<出荷システム>>
--
出荷を完了する"
物流 -> 出荷を完了する

usecase オーダー状況を確認する as "<<出荷システム>>
--
オーダー状況を確認する"
顧客 -> オーダー状況を確認する

usecase 出荷を指示する as "<<出荷システム>>
--
出荷を指示する"
オーダー部門 -> 出荷を指示する

usecase 入金を確認する as "<<決済システム>>
--
入金を確認する"
オーダー部門 --> 入金を確認する

rectangle 商品販売サイト {
  営業 --> (商品を登録する)
  営業 --> (販売状況を照会する)

  (商品を説明する) <-- 顧客
  (商品を注文する) <-- 顧客

  物流 --> (オーダーを照会する) : 新規受注を確認する

  (オーダーを取り消す) <-- オーダー部門
  (オーダーを完了する) <-- オーダー部門
  (オーダーを照会する) <-- オーダー部門 : 出荷予定を確認する
  (入金額を補正する) <-- オーダー部門
}
```

```plantuml
left to right direction

actor 営業
actor 物流
actor 顧客
actor オーダー部門

usecase 商品を発注する as "<<入荷システム>>
--
商品を発注する"
営業 -> 商品を発注する
商品を発注する <- 物流

usecase 入荷商品を登録する as "<<入荷システム>>
--
入荷商品を登録する"
物流 -> 入荷商品を登録する

usecase 出荷を完了する as "<<出荷システム>>
--
出荷を完了する"
物流 -> 出荷を完了する

usecase オーダー状況を確認する as "<<出荷システム>>
--
オーダー状況を確認する"
顧客 -> オーダー状況を確認する

usecase 出荷を指示する as "<<出荷システム>>
--
出荷を指示する"
オーダー部門 -> 出荷を指示する

usecase 入金を確認する as "<<決済システム>>
--
入金を確認する"
オーダー部門 --> 入金を確認する

rectangle 商品販売サイト {
  営業 --> (商品を登録する)
  営業 --> (販売状況を照会する)

  (商品を説明する) <-- 顧客
  (商品を注文する) <-- 顧客

  物流 --> (オーダーを照会する) : 新規受注を確認する

  (オーダーを取り消す) <-- オーダー部門
  (オーダーを完了する) <-- オーダー部門
  (オーダーを照会する) <-- オーダー部門 : 出荷予定を確認する
  (入金額を補正する) <-- オーダー部門
}
```

---

## データモデル

- [オブジェクト図](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48#object)でシステムで扱うデータを整理します。
- `:` を利用してフィールドを記述します。

```
left to right direction

object 入金情報
入金情報 : 入金日
入金情報 : 入金者名
入金情報 : 金額

object オーダー情報
オーダー情報 : オーダーID
オーダー情報 : オーダー日
オーダー情報 : 決済方法

object 出荷指示情報
出荷指示情報 : 出荷予定日
出荷指示情報 : 入荷待ちの有無

object 出荷情報
出荷情報 : 出荷番号
出荷情報 : 出荷予定日

object 送り先情報
送り先情報 : 送り先名
送り先情報 : 郵便番号
送り先情報 : 住所
送り先情報 : 電話番号

object オーダー商品
オーダー商品 : 数量

object パッケージ
パッケージ : 商品名
パッケージ : 荷姿
パッケージ : 商品カテゴリ
パッケージ : 単価

object 取引先
取引先 : 名前
取引先 : 締め日

object 商品
商品 : 発注単位
商品 : 追加発注禁止

入金情報 "0..1"- オーダー情報

オーダー情報 "1"--"1" 出荷指示情報
出荷指示情報 <.. 出荷情報

オーダー情報 "1"--"1" 出荷情報

オーダー情報 o--"1" 送り先情報
送り先情報 <.. 出荷情報

オーダー情報 *--"*" オーダー商品 : オーダー商品
オーダー商品 <.. 出荷情報

オーダー商品 --"1" パッケージ
パッケージ o-"*" パッケージ
パッケージ <|-- 商品

取引先 - 商品
```


```plantuml
left to right direction

object 入金情報
入金情報 : 入金日
入金情報 : 入金者名
入金情報 : 金額

object オーダー情報
オーダー情報 : オーダーID
オーダー情報 : オーダー日
オーダー情報 : 決済方法

object 出荷指示情報
出荷指示情報 : 出荷予定日
出荷指示情報 : 入荷待ちの有無

object 出荷情報
出荷情報 : 出荷番号
出荷情報 : 出荷予定日

object 送り先情報
送り先情報 : 送り先名
送り先情報 : 郵便番号
送り先情報 : 住所
送り先情報 : 電話番号

object オーダー商品
オーダー商品 : 数量

object パッケージ
パッケージ : 商品名
パッケージ : 荷姿
パッケージ : 商品カテゴリ
パッケージ : 単価

object 取引先
取引先 : 名前
取引先 : 締め日

object 商品
商品 : 発注単位
商品 : 追加発注禁止

入金情報 "0..1"- オーダー情報

オーダー情報 "1"--"1" 出荷指示情報
出荷指示情報 <.. 出荷情報

オーダー情報 "1"--"1" 出荷情報

オーダー情報 o--"1" 送り先情報
送り先情報 <.. 出荷情報

オーダー情報 *--"*" オーダー商品 : オーダー商品
オーダー商品 <.. 出荷情報

オーダー商品 --"1" パッケージ
パッケージ o-"*" パッケージ
パッケージ <|-- 商品

取引先 - 商品
```

---

[モデルベース要件定義テクニック](https://www.shuwasystem.co.jp/book/9784798039442.html)の書籍を読まれたことがある方は図の再現度が高いと思われるかもしれません。PlantUML は工夫をすると色々な表現ができるので気なることは[年表](https://github.com/kurubushi--rm/history-in-UML)などでも UML にしてみましょう。