UMLクラス図記述のための、PlantUML、Mermaid、D2導入

# 概要

プログラム設計を行うために、UMLクラス図を書きたいとします。
ですが、手動でクラスや矢印の配置を調節するのは困難な作業となります。

世の中便利なもので、クラス間の関係をテキストで記述すれば、自動で配置を行い図の生成をしてくれるツールがあります。
この記事では「テキストベース作図ツール」、あるいは誤解のない文脈では単に「作図ツール」と呼ぶことにします。

筆者は先日、PlantUML、Mermaid、D2という3つの作図ツールを試用しました。そこで、これらの使用感および導入方法など、知見を書き残しておきます。

# 注意書き

筆者には、どの作図ツールが優れているという結論を出せていません。また執筆時間の都合上、実際の作図例を載せることもできていません。ですが、それらをご自身の手で試して頂くための助けにはなると思います。

また、これらの作図ツールの用途は、本来UMLクラス図のみに限られたものではありません。ですがこの記事では、クラス図に関する性質のみを取り上げます。

# 動機

筆者は個人でゲーム制作に取り組んでおり、UnityのためにC#を書いています。そこで、
[グローバルゲームジャムでクラス設計をやった話2020 #Unity - Qiita](https://qiita.com/toRisouP/items/6fdef63412db97970a11)
のようなクラス図を、半自動で書かせたいです。

テキストベース作図ツールを探したところ、前述の3つが見つかりました。
どれを使うのが良いのでしょうか?
実際に3つの作図ツールを試用してみることにしました。

# 要件

- UnityにおけるC#コードのクラス設計のスケッチを目的とする。
- 設計の概要がスケッチできればよく、他人に渡す正式なドキュメントを作る必要は薄い。
- 数ヶ月後に見直したり編集する可能性はある。
- テキストによる定義と図のプレビューを、並べて編集したい。
- 定義の編集が、図へと高速に反映されると良い。
- パッケージを含む図をきれいに描写できると望ましい。
- 図はある程度のサイズとなるため、マウス操作で簡易にズームやパンできると良い。
- VSCodeにて書けることが望ましいが、オンライン版でも良い。
- エディタには、構文認識やカッコの補完といった一般的な補助機能が欲しい。
- 可読性を損ねない範囲で、記法は簡潔である方が望ましい。
- 使用頻度が非常に低いため、あまりお金をかけたくない。

# 参考資料

## 比較サイト

[Text to diagram](https://text-to-diagram.com/?example=class)

これは作図ツールの一つ"D2"の製作元Terrastructが作っているサイトです。3つの作図ツールを比較しています。なお彼らの主張によれば比較は公平で、D2を贔屓するような要素はないとのことです。

ただ、このサイトの"Class"の比較において取り上げられている例は、非常に小さいです。先述のtoRisouPさんの記事にあるような、

- 大規模な図
- パッケージを含んだ図

において、どのような挙動や使い心地となるかはわかりませんでした。

## その他参考記事

[Mermaid記法とPlantUMLを比較する、どちらを採用すべきか？](https://zenn.dev/manase/scraps/415300a7a0631f)

[これからのText to DiagramツールはD2で決まり！ #WSL2 - Qiita](https://qiita.com/inTiramisu/items/33391efb1f407613fef2)

[PlantUML使い方メモ #Java - Qiita](https://qiita.com/opengl-8080/items/98c510b8ca060bdd2ea3)

# 事前知識：レイアウトエンジン

作図ツールは、実際には2つの部分に分かれています。定義に使うツール本体と、ツールが利用する図のレイアウトエンジンです。
図のレイアウトエンジンは、箱（クラスなど）と矢印の位置決めを司っています。箱や矢印自体の見た目を決めるのはツール本体ですが、それらの配置はレイアウトエンジンによって大きく変動します。
ツールによって使えるレイアウトエンジンが異なっています。

| PlantUML | Mermaid | D2    |
|:---------|:--------|:------|
| DOT      | Dagre   | Dagre |
| ELK      |         | ELK   |
|          |         | TALA  |

このあたりの事情は、D2のドキュメントに詳しいです。（彼らはTALAのライセンスで商売をしているので、このあたりを説明する動機があるのです。）
各エンジンの長所と短所もこちらに載っていますので、ここでは詳述しません。

[Layouts > Overview | D2 Documentation](https://d2lang.com/tour/layouts)

簡単に補足します。

まずDagreやDOTでは、パッケージを含めた大規模な図において、クラスの箱の下に矢印が隠れてしまうケースが見られました。パッケージを使わなければ、この傾向は緩和されます。

また、矢印の密集度が高い場合、矢印の線同士が重なって判別がつかなくなってしまうこともあります。

次にTALAです。これは有償のエンジンで、D2と同じTerrastruct社が作っています。

[Terrastruct | Diagramming tools crafted to visualize software architecture](https://terrastruct.com/#pricing)

2024/06時点で、$20 month/userとなっています。

TALAの評価版は無償で試用できますが、図の中央に大きくグレーで"UNLICENSED COPY"という文字が入ります。

好みの範疇ですが、TALAの生成した図は見やすく感じました。TALAを利用できること自体を、D2の強みの一つに数えても良いでしょう。

最後にELKです。これは無償で利用でき、矢印が重なることもありません。ですが、多数の矢印が隣接して平行に走る図を生成することが多いです。これも個々人の好みになると思いますが、私は目が滑ると感じました。

# 各ツールの解説

ここからは各々の作図ツールについて述べていきます。

## PlantUML

[公式サイト](https://plantuml.com/ja/)

[オンライン版](http://www.plantuml.com/)

### 導入方法

残念ながらPlantUMLのオンライン版は現代の基準に達していません。エディタは構文も認識しなければカッコの補完もしてくれませんし、生成した図はズームもパンも全くできません。軽く試す分にはいいですが、本格的に作るならVSCodeにて使うのが良いでしょう。

私は拡張機能の
[PlantUML](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)
を入れました。これにはPlantUML本体も内蔵されています。

ELKとの組み合わせを試したい場合は、
[plantuml.com/ja/elk](https://plantuml.com/ja/elk)
の手順に従う必要があります。この場合、内蔵のPlantUMLを使えません（恐らく）。ですので、具体的には以下のようにすると良いでしょう。

- plantuml.jar を https://plantuml.com/ja/download の"Compiled jar"からダウンロードする。
- elk-full.jar を https://plantuml.com/ja/elk の"the complete jar file here"からダウンロードする。
- 適当なフォルダを作り、plantuml.jarとelk-full.jarを並べて入れる。
- 拡張機能の設定を開き、"Plantuml: Jar" (plantuml.jar で検索)に今置いたplantuml.jarのパスを入れる。
- テキスト定義に`!pragma layout elk`と書く。

ちなみに、オンライン版にて`!pragma layout elk`を書くとエラーになります。

### おすすめの記法

"-->"の矢印を書くとき、ハイフンの個数で矢印の長さを調節できます。

他のパッケージのクラスを参照するためには、
```
ClassA -> .PackageX.ClassB
```
とします。
これを使わない場合でも、PackageX内にClassBの定義がされていれば、正しく参照できます。逆に、定義がない場合、ClassAと同じパッケージ内にClassBがあると解釈されます。
私はいちいちClassBの定義をするのは冗長な場合もあるので、パッケージを明示した方が速いと思ってるのですが、これは好みの範疇でしょう。

私は図を見やすくするために
```
skinparam classAttributeIconSize 0
hide empty members
```
を入れました。これも好みの範囲でしょう。

### 使い心地

拡張機能は快適です。図のプレビューでは、クリックでズーム・右クリックでパンができます。

数十のクラスを定義すると、矢印がぴったり重なって解読不能になってしまうことがありました。この傾向は、特にパッケージを定義した場合に悪化しました。これは先述したDOTの特性かもしれませんが、まだ検証できていません。

小さな図やパッケージを含まない図では、問題なく使えます。

## Mermaid

[Home | Mermaid Chart](https://www.mermaidchart.com/)

[Online FlowChart & Diagrams Editor - Mermaid Live Editor](https://mermaid.live/)

Mermaidの特記事項として、GithubやQiitaを始めとするサービス群と連携している点があります。MarkdownにMermaid記法を埋め込める機能があり、テキスト定義を書くと自動で図に変換してくれます。これだけでも、Mermaidを使う理由になると思います。

### 導入方法

結論から言いますと、無償の範囲では、VSCodeの拡張機能でMermaidをうまく使えませんでした。無償でMermaidを使う場合は、オンラインエディタを使うのが良いと思います。

ただし、オンラインエディタで編集した内容をブラウザ上で保存するには、"Mermaid Chart"サービスにユーザー登録して連携する必要があるようです。2024/06時点にて、無料プランでは5つのファイルしか保存できないと書かれています。

[Pricing | Mermaid Chart](https://www.mermaidchart.com/pricing)

他には、
- gistとして出力する方法
- URLをコピーして取っておく方法
- ローカルファイルにコピペする方法

などが考えられますが、私はかなり面倒だと思いました。

### 補足：拡張機能のレビュー

VSCodeのMermaid用拡張機能について補足しておきます。私が見たところ、候補に挙がるのは4つあると思いました。

[Markdown Preview Mermaid Support - Visual Studio Marketplace]( https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)

最もインストールされている拡張のようです。Markdownに埋め込まれたMermaid記法に対応してくれます。
しかしこの拡張には問題があります。まず、構文ハイライトを行ってくれません。そして、Markdownに埋め込んで表示する都合上、図をズームして見ることができません。さらに、独立したファイル(.mmd)として記述することもできず、必ずMarkdownに埋め込む必要があります。

[Mermaid Preview - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=vstirbu.vscode-mermaid-preview)

こちらは独立したファイルを扱うことができます。しかし、やはりプレビューした図をズームすることはできません。

[Mermaid Chart - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=MermaidChart.vscode-mermaid-chart)

こちらは公式の拡張機能です。この拡張機能を使うには、前述の"Mermaid Chart"サービスのアカウント連携が必要となるようです。私は試していません。

https://docs.mermaidchart.com/plugins/visual-studio-code#requirements

> The Mermaid Chart extension seamlessly integrates with the Mermaid Chart service. To use the extension, you need an account. You can choose between the Free tier, which is limited to 5 diagrams, or the Pro tier with unlimited diagrams.

[Mermaid Editor - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=tomoyukim.vscode-mermaid-editor)

これは`mermaid.js`を内蔵した拡張機能です。最初何を言ってるかわからなかったのですが、どうやら`mermaid.js`というのは元々Githubで公開されているオープンソースプロジェクトであり、このライブラリ自体は無料で使えるようです。そこから派生したのが営利企業の"Mermaid Chart"社だそうです。

[Mermaid | Diagramming and charting tool](https://mermaid.js.org/)
[Company | Mermaid Chart](https://www.mermaidchart.com/company)

要するにこの拡張機能を使えば、無償でもファイル数制限を気にせずに作図できるわけです。
しかし結局のところ、この拡張機能もおすすめできません。使い勝手が非常に悪いからです。エディタの編集補助がありませんし、文法エラーを起こしても爆弾マークが表示されるだけで、エラーが何行目かもわかりませんでした。

### おすすめの記法

クラス図に関して特に難しいことはありません。公式で書いてある通りに書けばうまく行くでしょう。
ただし、1点だけ注意があります。ジェネリックを表現するとき、なぜか<>で囲むことができず、`~`を用いる必要があります。そして、`List<List<K, V>>`のような多層かつカンマを含むジェネリックはサポートされていません。

[Class diagrams | Mermaid](https://mermaid.js.org/syntax/classDiagram.html#generic-types)

### 使い心地

ブラウザ版の使い心地はかなり良いです。"Auto Sync"は重くなるので、これだけ切っておいてCtrl + Enterで更新すると良いでしょう。

ただ、ツールの使用感以前の問題として、無償では書いたテキストファイルを保存しにくいのが気になってしまいました。有償プランに入ればまた感想が変わるのかもしれません。

## D2

[Home | D2 Documentation](https://d2lang.com/)

[D2 Playground](https://play.d2lang.com/)

### 導入方法

D2のオンライン版は快適です。これを使ってもよいと思います。

VSCodeの場合、Tesseruct謹製の拡張機能があります。
https://marketplace.visualstudio.com/items?itemName=terrastruct.d2

ただし、拡張機能の説明にある通り、別途D2を環境にインストールしなければいけません。

https://github.com/terrastruct/d2/tree/master#install

https://github.com/terrastruct/d2/blob/master/docs/INSTALL.md

私はWindowsネイティブ環境なので、msiファイルで入れました。

レイアウトエンジンの切り替えは、拡張機能の設定の"d2.previewLayout"でできます。ここでTALAを使いたい場合は、TALAも別で環境にインストールする必要があります。

https://github.com/terrastruct/TALA?tab=readme-ov-file#installation

私はこれもmsiで入れました。（有償版は使っていないので、有償版のインストール方法はわかりません。）

### おすすめの記法

[UML Classes | D2 Documentation](https://d2lang.com/tour/uml-classes)
にある通り、`shape: class`を設定することで、UMLを意識したフィールドとメソッドの区分をつけてくれます。ただ、全体としてD2のUMLサポートは、PlantUMLやMermaidに比べて限られています。

パッケージ専用の記法はないため、パッケージを表現したい場合は、コンテナ機能を流用することになります。

[Containers | D2 Documentation](https://d2lang.com/tour/containers)

コンテナ外のクラスを参照したい場合は、
```
_.ContainerA.ShapeA
```
のように_を用います。

また小さなテクニックですが、公式ドキュメントの説明通りに考えると、全てのクラス定義に毎回
```
shape: class
```
を書かなければいけないことになります。これはGlobs機能で緩和できます。
パッケージを使う場合は
```
*.*.shape: class
```
使わない場合は
```
*.shape: class
```
を最初に記述することで、記述量を減らせます。

[Globs | D2 Documentation](https://d2lang.com/tour/globs)

### 使い心地

TALAを試用した場合の見やすさは非常に良かったです。パッケージを最初から考慮に入れていると公言しているだけのことはあります。

拡張機能への印象は悪いです。なぜなら、プレビューにて、マウスドラッグで図を移動できず、いちいちスクロールバーにマウスを移動させなければいけないからです。ズームもホイールやクリックで操作できませんでした。

ただ、シンタックスエラーを詳細に出してくれるのは便利です。

今回の主題から外れますが、UMLクラス図以外での応用可能性が高いと思いました。特に、図やアイコンをURL参照で簡単に挿入できるのは素晴らしいです。

VSCodeで使うのはもろもろ大変なので、結局D2もオンラインエディタで使った方が丸いかもしれません。

# まとめ

UMLクラス図生成のため、PlantUML、Mermaid、D2という3つのテキストベース作図ツールを試用してきました。どのツールが最も優れているということはなく、長所短所がありますので、各人の目的に合ったものを選ぶのが良いと思われます。この記事がその助けになれば幸いです。

# 感想

私はPlantUMLのDOTにして、パッケージを含む大規模な図は諦め、図は小さく分割しようと思いました。

UMLではないですが、小説の人物相関図とか作るときは、D2がいいかもしれないです。