ATOM エディタを使った作図(PlantUML 編)

no extension

前回ATOM エディタの掃除も終わったので,以前から気になっていた「PlantUML を使った作図」について調べてみた。 ええ,分かってますとも。 前回に引き続き「現実逃避」というやつです。

ATOMPlantUML 関連パッケージを導入する

PlantUML 自体は UML (Unified Modeling Language; 統一モデリング言語) を記述するための DSL (Domain-Specific Language; ドメイン特化言語) と考えてよい(実際には UML 以外のものも記述可能)。 UML の構文(に相当するもの)は図形で表されるが,それをテキストで記述できるようにしたのが PlantUML である。 「UML って何?」って方もおられるだろうが,それは後ほど説明する。

直前に述べたように PlantUML 自体はテキストで記述するが,最終的には図(diagram)に落とし込むため Graphviz と Java の実行環境が必要となる1。 これらをあらかじめ導入しておくこと(導入方法については割愛する)。

ATOM で UML を書く(描く)ために以下の2つのパッケージを導入する。

language-plantuml は(今のところ)ハイライト機能しかないようなので無くても構わないが, plantuml-viewer は描画に必要なので必ず導入すること。

plantuml-viewer を導入したら Settings を開いて “Charset” および “Graphviz Dot Executable” 各項目の設定をしておく。

settings of plantuml-viewer package
settings of plantuml-viewer package

“Graphviz Dot Executable” 項目には Graphviz の dot コマンドへのフルパスをセットする。 “Charset” 項目については, ATOM で書くんだから UTF-8 にしておけばいいだろう。

最初はやっぱり Hello World でしょ

動作確認を兼ねて何か書いてみる。

language-plantuml では .pu, .puml, .plantumlPlantUML 用の拡張子と認識するようなので,まずは hello.puml ファイルを作って以下のように記述する。

Bob->Alice : hello

これを plantuml-viewer で表示する(ctrl-alt-p でビュアーが開く)。

おおっ。 できたできた。 表示されている図は PNG, SVG, EPS のいずれかの形式で保存できる(コンテキスト・メニューから “Save As …” を選択する)。

PlantUML@startuml ... @enduml の間を記述領域と見なすようで

ほげほげ

@startuml
  Bob->Alice : hello
@enduml

ほえほえ

と書いても,全く同じ図が出力される。 他形式のドキュメントに埋め込むことを想定してのことだろうが3,今回は単純に図が出力できればいいので,以降の記述では @startuml および @enduml を省くことにする。

見た目の調整

このままでもいいっちゃあいいのだが,もう少し見た目をどうにかしたい。 まずはモノクロ表示にしてみる。

skinparam monochrome true
Bob->Alice : hello

これで

という感じにモノクロになった。 調子に乗ってもう少し色々と弄ってみよう。

skinparam shadowing false
skinparam default{
  FontName 'Noto Serif', 'Noto Serif JP', serif
  FontColor black
  FontSize 14
}
skinparam sequence {
  ArrowColor Black
  ArrowFontName 'Noto Sans', 'Noto Sans JP', sans-serif
  ArrowFontColor black
  ArrowFontSize 10
  LifeLineBorderColor Black
  LifeLineBackgroundColor White
  ActorBorderColor Black
  ActorBackgroundColor White
  ParticipantBorderColor Black
  ParticipantBackgroundColor LightGray
  MessageAlign center
}

actor ボブ
participant Alice

ボブ->Alice : こんにちは
activate Alice

Alice-->ボブ : Hello
deactivate Alice

前半部分で線や背景色の色およびフォントについて指定し4,後半部分で実際のシーケンスを記述している。 これを SVG に出力するとこんな感じになる。

見た目の記述に毎回あれだけの量を書くのはかったるいのでインクルードファイルとして別出ししてしまおう。

!include style.puml

actor ボブ
participant Alice

ボブ->Alice : こんにちは
activate Alice

Alice-->ボブ : Hello
deactivate Alice

これでスッキリした。 style.puml ファイルの中身はこんな感じで,記述をそのままコピっただけ。

skinparam shadowing false
skinparam default{
  FontName 'Noto Serif', 'Noto Serif JP', serif
  FontColor black
  FontSize 14
}
skinparam sequence {
  ArrowColor Black
  ArrowFontName 'Noto Sans', 'Noto Sans JP', sans-serif
  ArrowFontColor black
  ArrowFontSize 10
  LifeLineBorderColor Black
  LifeLineBackgroundColor White
  ActorBorderColor Black
  ActorBackgroundColor White
  ParticipantBorderColor Black
  ParticipantBackgroundColor LightGray
  MessageAlign center
}

PlantUML で作図可能な UML 図

現在 UML 2.0 では以下の図(Diagrams)が定義されている。

リンクがあるものが PlantUML 記述可能な図である。

UML 各図の中の線や図形は全て「意味」が決められており,それらを組み合わせることでシステムの仕様や設計が表現できることを目指している。 名前が示す通りモデリングの設計手法と相性がいいため,オブジェクト指向設計においてよく使われる。

実際には上で挙げた図を全て駆使するのではなく,システムの性格や規模に応じて幾つかの図を組み合わせて使うのが普通である。

UML 図の中でもよく使われるシーケンス図とクラス図について PlantUML での記述を紹介しよう。 以前「そうだ,シーケンス図を描こう!」の中で, mermaid 記法で書いたシーケンス図

sequenceDiagram カバ->>+カバン: あなた,泳げまして? カバン-->>-カバ: いえ カバ->>+カバン: 空は飛べるんですの? カバン-->>-カバ: いえ カバ->>+カバン: じゃあ,足が速いとか? カバン-->>-カバ: いえ カバ->>カバン: あなた,何にもできないのねぇ loop ひとりヘコむ カバン->>カバン: ううっ end
カバとカバン

PlantUML で作図するとこんな感じだろうか(図のリンク先が PlantUML ソースコード)。

カバとカバン
カバとカバン

じゃあ, mermaid 記法で書いたクラス図

classDiagram friends<|--serval friends<|--raccoon friends<|--fennec serval : +Waai() raccoon : +OmakaseNanoda() fennec : +Haiyo()
フレンズ

PlantUML で作図するとこんな感じかな(コメントをちょろんと加えてみた)。

フレンズ
フレンズ

おおっ。 流石にクラス図は PlantUML の方がいいな。 矢印は横向きにも出来るっぽい。

今度からクラス図描くときは PlantUML で描くようにしよう。

やっぱり考えながら描く

そうだ,シーケンス図を描こう!」でも書いたんだけど,クラス図やシーケンス図といったものは試行錯誤しながら描いていくものなのよ5。 お客さんもマネージャもプログラマも UML 図を中心に議論を行っていく。 だから作成や修正が面倒なツールはダメなのだ。 PlantUML は時々刻々と修正されることを前提にしたツールと言える。

もうひとつ。

要求定義を行っていくと「要求」やそれに伴う「仕様」が大きく変化することがある。 変化すること自体は(改善されてるってことだし)結構なのだが(予算規模が変わってアワアワする可能性はあるけど),あとからチームに参加する人たちは「結果」しか提示されないので「何故そのような「要求」に至ったか」が理解できないことが多い。 不完全な理解のまま作業をすすめると必ず何処かで不整合が起きる(つまり文脈(context)が大事ってこと)。

だから議論の流れを後から追えるよう「履歴」をとっていく必要がある。 私が最近 UML 図に関して教わったのは

  1. 最初は不完全でも間違ってても構わない。まずは考えていることを図にぶちまけることが重要
  2. ただし,クラス図では多重度を記述すること(MUST)
  3. 要求定義レベルの図と設計レベルの図は必要とされる詳細度や厳密度が異なる。最初から設計レベルの図を描こうとしないこと
  4. 作成した図は(手書きのものも含めて)全て履歴として保管し,後から参照できるようにすること

だったかな。

PlantUML の利点は,テキストであるが故に修正・変更が容易で, git などのバージョン管理システムと組み合わせて履歴から差分情報を抽出しやすいことにある。 ぶっちゃけ,出力としての PNG や SVG 画像ファイルにはさしたる価値はなく, UML 用の DSL である PlantUML の記述にこそ大きな価値があるということだ。

ブックマーク


  1. PlantUML の本体は plantuml.jar で提供されている。このファイルを使って “java -jar plantuml.jar -language” とコマンドを打つと PlantUML で使われる全シンボルが表示される。シーケンス図以外は内部で DOT 言語に変換してから Graphviz を使って作図するようだ。 [return]
  2. Windows なら %USERPROFILE%\.atom\packages\plantuml-viewer フォルダにインストールされるが,その中の node_modules\node-plantuml フォルダに plantuml.jar がある筈である。 [return]
  3. @startuml の後ろに images/hello.png などと指定すれば plantuml.jar のほうで自動的に指定したパス名で画像ファイルを出力するらしい。 [return]
  4. フォント名については font-family としてそのまま SVG に埋め込まれる。従って環境によって見え方が異なる筈である。どの環境でも同じような見え方にしたいなら PNG で保存するのが最も確実だろう。その場合は xxxFontName に自マシンにインストールされている具体的なフォント名を指定する必要がある。 [return]
  5. もちろん UML を CASE (Computer Aided Software Engineering) の入力手段として使う場合もある(つか UML ってそれを念頭に置いて開発されたものだからねぇ)。その場合は矛盾のない正確な記述が要求される。 [return]