設計時に使う図形描画系ツールの紹介

# はじめに

最近設計する事が多いのですが、自分の脳内整理用だったり、認識合わせ用によく図を作っています。
スピードが必要だったり、変更が加わる物なので楽に更新できるこんな感じの要件で選定しています。

- 設計時に書ける事
- コードで手早く書ける事
- クオリティや柔軟性は重視しない

それぞれのシーンで個人的に使ってるツールを紹介します。

# ER図

ER図はデータベースの構造を図にした物です。
APIを設計時に、どのようなデータを保持していて、APIで何ができるか、何ができないか、できないなら何を追加するべきかを図をみながら判断しやすくなります。

## erd

いろいろなツールで作成できますが、書きやすくカラム毎に色も変更できるので私は[erd](https://github.com/BurntSushi/erd)を利用しています。
これはerdでユーザーが商品を注文するサンプルです。

```
title {label: "example", size: "20"}

[users] {bgcolor: "#ffffff", label: "ユーザー"}
  *id
  name {label: "名前"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}

[goods] {bgcolor: "#ffffff", label: "商品"}
  *id
  name {label: "名前"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}

[orders] {bgcolor: "#ffffff", label: "注文"}
  *id
  +users_id {label: "ユーザーID"}
  +goods_id {label: "商品ID"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}

users 1--* orders
goods 1--* orders
```

![erd-er.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/5aaf97c5-dbc8-59ec-32e6-b3abcbe94049.png)

シンプルで良い感じです。
また、リリース後に

- カナが要らなくなったので削除
- 注文をキャンセルできるようにする

のような変更があった場合、色を変えてdiffのような表現ができるので説明がしやすくなります。

```
title {label: "example", size: "20"}

[users] {bgcolor: "#ffffff", label: "ユーザー"}
  *id
  name {label: "名前"}
  kana {label: "カナ", bgcolor: "#ffeeee"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}

[goods] {bgcolor: "#ffffff", label: "商品"}
  *id
  name {label: "名前"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}

[orders] {bgcolor: "#ffffff", label: "注文"}
  *id
  +users_id {label: "ユーザーID"}
  +goods_id {label: "商品ID"}
  created_at {label: "作成日時"}
  updated_at {label: "更新日時"}
  deleted_at {label: "削除日時", bgcolor: "#eeffee"}

users 1--* orders
goods 1--* orders
```

![erd-er-diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/4b1f9fa5-e06d-6c86-d059-2d0028220e3d.png)

## plantuml

また、[plantuml](https://plantuml.com/ja/ie-diagram)でもER図を作成できます。
定義によっては配置が変わったりする若干のクセがあるように感じましたが、メジャーなツールだし腐らないのでこれも良いかなと思います。

```
@startuml

entity "orders 注文" as orders {
  * id
  --
  +users_id: ユーザーID
  +goods_id: 商品ID
  --
  created_at 作成日時
  updated_at 更新日時
}

entity "users ユーザー" as users {
  * id
  --
  name 名前
  created_at 作成日時
  updated_at 更新日時
}

entity "goods 商品" as goods {
  * id
  --
  name 名前
  created_at 作成日時
  updated_at 更新日時
}

goods ||..|{ orders
users ||..|{ orders

@enduml
```

![plantuml-er.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/fd19cfc0-5aed-c974-be2d-d33c170e8cdc.png)


## 設計フェーズではないなら

番外辺ですが、途中からプロジェクトに入ったなど新規の設計フェーズではないなら使うツールも変わります。

### tbls

ワンコマンドで実DBに接続してER図を生成してくれる[tbls](https://github.com/k1LoW/tbls)を使って作ります。
システム概要把握のために一番最初にやるかもしれません。

> ![](https://github.com/k1LoW/tbls/raw/master/sample/postgres/schema.svg)
> *github k1LoW/tbls https://github.com/k1LoW/tbls より引用

### Mysql Workbench

もう少し綺麗な図が欲しい場合は[Mysql Workbench](https://www.mysql.com/jp/products/workbench/design/)でER図を自動生成後、
エディタで位置を整えたりする事で綺麗なER図ができます。


> ![](https://www.mysql.com/common/images/products/MySQL_Workbench_Visual_Design_Windows.gif)
> *Mysql Workbench公式 https://www.mysql.com/jp/products/workbench/design/ より引用

# フローチャート

複雑なシステムを設計する際に、流れを図式化できるフローチャートを作って説明する事ができます。

## mermaid

私は[mermaid flowchat](https://mermaid-js.github.io/mermaid/#/flowchart)を利用しています。
シンプルで書きやすいです。

```
graph TD

Buy[購入リクエスト]
IfStockExists{在庫があるか}
IfPaymentSuccess{決済完了したか}
ShowError[エラー表示]
Complete[完了]

Buy --> IfStockExists
IfStockExists -->|Yes| IfPaymentSuccess
IfStockExists -->|No| ShowError

IfPaymentSuccess -->|Yes| Complete
IfPaymentSuccess -->|No| ShowError
```

![mermaid-flowchart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/c05e3b2d-784b-dc03-d3a6-fc110880633a.png)

## plantuml

正式にはアクティビティ図ですが、[plantuml](https://plantuml.com/ja/activity-diagram-legacy)を利用して流れを図式化する事もできます。

```
@startuml
:購入リクエスト;
if (在庫があるか) then (Yes)
  if (決済完了したか) then (Yes)
    :完了;
    kill
  else (No)
    :エラー表示;
    kill
  endif
else (No)
  :エラー表示;
  kill
endif
@enduml
```

![plantuml-flowchart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/8b010b4f-d3e6-78b4-fdac-f41b7f90daed.png)

# シーケンス図

認証フローなど、システム間の通信の動作などを図式化したい時にシーケンス図を作ります。

## mermaid

[mermaid sequence diagram](https://mermaid-js.github.io/mermaid/#/sequenceDiagram)を利用して作成できます。
簡単な例ですが、これもシンプルで書きやすいです。

```
sequenceDiagram

Alice->>Bob: 公開鍵要求
Bob->>Alice: 公開鍵
Alice->>Alice: 公開鍵でデータを暗号化
Alice->>Bob: 暗号化したデータ
Bob->>Bob: 暗号化したデータを秘密鍵で複合化
```

![mermaid-sequence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/ea6b0489-0539-ac75-7b95-a491ef583f80.png)

## plantuml

[plantuml](https://plantuml.com/ja/sequence-diagram)でも作成できます。
使い勝手はmermaidとあまり差はないので好みで選んで良いと思います。

```
@startuml
Alice --> Bob: 公開鍵要求
Bob --> Alice: 公開鍵
Alice --> Alice: 公開鍵でデータを暗号化
Alice --> Bob: 暗号化したデータ
Bob --> Bob: 暗号化したデータを秘密鍵で複合化
@enduml
```

![plantuml-sequence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/13b53e22-59f3-4808-825a-f3d0013a4b63.png)

# 他にも

[mermaid](https://mermaid-js.github.io/mermaid/#/)は他にも[クラス図](https://mermaid-js.github.io/mermaid/#/classDiagram)、[状態遷移図](https://mermaid-js.github.io/mermaid/#/stateDiagram)、[ガントチャート](https://mermaid-js.github.io/mermaid/#/gantt)、[円グラフ](https://mermaid-js.github.io/mermaid/#/pie)などに対応しています。
[plantuml](https://plantuml.com/ja/)はもっと多くて、それ以外にも[ユースケース図](https://plantuml.com/ja/use-case-diagram)、[オブジェクト図](https://plantuml.com/ja/object-diagram)、[コンポーネント図](https://plantuml.com/ja/component-diagram)、[タイミング図](https://plantuml.com/ja/timing-diagram)、変わった物だと[ワイヤーフレーム](https://plantuml.com/ja/salt)までかなり多くの範囲をカバーしています。

# 所感

クオリティや柔軟性を重視するなら[draw.io](https://app.diagrams.net/)や[Google図形描画](https://docs.google.com/drawings)などを使ったりしますし、使用しているツールなどに付属する図形吐き出し機能があるのであればその方が簡単で綺麗にできると思います。
作成時間や更新の手間と必要なクオリティを考慮して適切なツールを選ぶといいでしょう。

後半はほぼmermaidとplantumlの紹介みたいになってしまいましたが、どれもそれぞれ良いところがあります。
markdownのシンタックスハイライトに対応してたり、live editorがあるので気になる方は試してみてはいかがでしょうか。

- [mermaid live editor](https://mermaid-js.github.io/mermaid-live-editor)
- [plantuml live editor](https://plantuml-editor.kkeisuke.com/)