morishitaです。
開発の中でドキュメントを書くことがあると思います。
しっかりした仕様書を作成するところもあるでしょうし、重要な部分のみメモ程度ということもあると思います。
ドキュメントでは文章を書くことが多いとは思いますが、文章だけでは説明が難しい場合、図を書いたりすると思います。 システム開発での図というとクラス図やフローチャートなどかと思います。
独自の記法だと見せられる方が困るので、とりあえず厳密でなくても UML を利用しているのではないでしょうか。
今回は UML を描くときに便利な PlantUML について書きます。
UML とは? そして PlantUML とは?
PlantUML の話をする前に UML とは何でしょうか?
システムを開発する場合にはシステム化対象の要件を抽象化して設計に落とし込む必要があります。文章で仕様を記述したりもしますが、モデルとモデルの関係や相互作用を表すには文章よりも図にしたほうがわかりやすい場合が多いです。
また、すでにあるシステムの構造を理解するためにクラス間の関係を図に書いたりすることもあるかと思います。
そんなときによく使われる図の記法が UML です。
UML は Unified Modeling Language の略で、日本語に訳すと「統一モデリング言語」1と呼ばれるものです。
システム構成やソフトウェアの構造や振る舞いを表す図の記法を定めたもので、従来存在していたいくつかの記法の考案者2が協力して 1 つに集約した記法です。
UML の仕様はOMG | Object Management Groupという団体により管理されています。
UML では構造図 (Structure Diagrams) 7 種、振る舞い図 (Behaviour Diagrams) 3 種、相互作用図 (Interaction Diagrams) 4 種の 14 種の図が定義されています。
14 種類の図をすべてを利用する必要はなく、モデル化したい対象を表すのにふさわしいもの必要に応じて選択して利用します。
(出典:Unified Modeling Language - Wikipedia)
クラス図やシーケンス図などはシステム開発の現場ではよく使われていると思うので見た事あるのではないでしょうか。 また、システム開発だけではなく、ビジネスプロセスのモデリングや組織の構造図を表現するのにUML が使われることもあるようです。
そして PlantUML はこの UML をテキストで記述できるツールです。
独自の記述方法があり、詳しく公式サイトで説明されています。
PlantUML が利用できる環境
公式のオンラインサーバにブラウザでアクセスすればすぐに描くことができます。 公式の Docker イメージplantuml/plantuml-serverを利用すれば、公式のオンラインサーバと同等ものがローカルで動かせます。
そもそも Jar にパッケージされたモジュールなのでそれを利用してPlantUMLを記述したテキストファイルから UML の画像ファイルを出力することもできます3。
公式ツールは PlantUML で書いたものを画像として図化してくれるツールですが、
UML の図を単体で描くのではなくドキュメントの中に書きたい場合のほうが多いのではないかと思います。なので手軽に PlantUMLを利用する環境としては VSCode の拡張 Markdown Preview Enhancedがオススメです4。Markdownファイルの中で PlantUMLで書いた図を埋め込めます。
Markdown なメモアプリ Obsidianでもobsidian-plantumlプラグインをインストールすると使えるようになります。
また、Kibela、esaといった Markdown 形式で記述できるドキュメント共有サービスでもサポートされています。文章中に PlantUML で図を入れることができます。
アクトインディではドキュメントの共有に esaを利用しているので私は主にそこで使っています。
PlantUMLで描けるUML
PlantUML がサポートしている UML の図は 9 種類です。 順に見ていきましょう。
ユースケース図
システムが提供するサービスとそれに関係する外部要素(ユーザや外部システム)の関係を表すのがユースケース図です。
楕円でユースケースを人形はそのサービスを利用するアクター(ユーザや外部システム)を表します。
個々のユースケースがどういうことをするのかは表さないので必要ならユースケース記述等で補います。
上のユースケース図は次のPlantUMLの記述で生成しました。
@startuml left to right direction actor "メンバー" as member actor "イベンター" as eventer rectangle "いこーよ" { usecase "お出かけ先をさがす" as uc1 usecase "イベントをさがす" as uc2 usecase "イベントを登録する" as uc3 } member --> uc1 member --> uc2 eventer -up-> uc3 @enduml
タイトルだけでおおよその内容の見当がつくシンプルなユースケースならユースケース図だけシステムが提供するサービスの全体像を把握するには十分かと思います。
クラス図
モデルの静的な関係を表す図で、問題領域やシステム化対象領域にあるモデル要素の構造を表します。
モデル要素とはクラスです。クラスの構造とクラス間の関係によって問題領域やシステム化対象領域を表現します。
UML の中では最重要かつ最も利用される図であり、他の図はなくてもクラス図だけは書く場合も多いと思います。
上のクラス図は次のPlantUMLの記述で生成しました。
@startuml class User class Member class Child class Eventer Class Event Member -up-|> User Member *--"0..*" Child Eventer -up-|> User Eventer --"0..*" Event @enduml
オブジェクト図
クラス図がクラスの構造、関係を表すのに対して、オブジェクト図はオブジェクトが保持するデータ、オブジェクトの間の関係を表します。
クラスを具象化したものであるオブジェクト(インスタンス)を描くのでシステムのある時点でのスナップショットを表します。
クラスのインスタンスが具体的にどの様な値を持ち、どの様な関連を持つのか理解するのに役立つとは思いますが、わざわざ描くのも面倒なのであんまり使われないと思います。
シーケンス図
問題領域やシステム化対象領域のモデル要素がどのようなやり取りをすのかという振る舞いを表すのがシーケンス図です。
クラス間のメソッドの呼び合いやシステム間のAPIのやり取りなど複数のモデル要素にまたがった処理を時系列順に表すのに便利です。
上のシーケンス図は次のPlantUMLの記述で生成しました。
@startuml actor "イベンターA" as user participant ":イベント登録画面" as form participant ":イベントコントローラ" as event_ctrl user -> form: イベント情報を入力 form -> event_ctrl: イベント登録 event_ctrl --> form: 登録情報 form -> form: 登録結果表示 @enduml
アクティビティ図
アクティビティ図では業務や処理の流れを表します。フローチャート呼ばれるものと役割も見た目も近しいかと思います。
上のアクティビティ図は次のPlantUMLの記述で生成しました。
@startuml |イベンター| start :イベントを企画する; :イベントを情報を入力する; |いこーよ| :イベントを登録する; :イベントを表示する; |参加者| :イベント情報を見る; :イベントに参加申込する; |いこーよ| :イベント参加登録する; |イベンター| :イベントを開催する; stop @enduml
コンポーネント図
システム内のコンポーネント構成、関連を表す図がコンポーネント図です。
上のコンポーネント図は次のPlantUMLの記述で生成しました。
@startuml [Webポータル] as web [チケット販売サブシステム] as ticket interface "チケットAPI" as ticket_api ticket_api - ticket [決済サブシステム] as payment interface "決済API" as payment_api payment_api - payment web -> ticket_api ticket -> payment_api @enduml
アプリケーションサーバと DB だけで構成されるようなシンプルなシステムではまあ、必要ないと思います。
モノリスな Rails アプリケーションでも DB 以外に様々なミドルウェア、サービスを利用している場合に全体を俯瞰するには役立つと思います。
マイクロサービスでシステム構築しているところではもっと便利で役立つかもしれません。
配置図
配置図はシステムの物理的な構造を表します。例えばどの様な種類のサーバを立てて、その中でどの様なプロブラムを動かすのかといったことを図示できます。
UML の中でも比較的低レイヤーを表す図です。どのサーバに障害が発生すると何が止まるのかを把握するのに役立つのではないでしょうか。
上の配置図は次のPlantUMLの記述で生成しました。
@startuml node UI <<Pod>> { artifact クーポンサイト <<nuxt>> as portal } node API <<Pod>> { artifact クーポンAPI <<rails>> as api interface "/coupons" as coupons coupons - api } portal -down-> coupons @enduml
状態遷移図(ステートマシン図)
1 つのオブジェクトの状態変化を表した図です。 Web システムだとできるだけステートレスに設計するのでそれほど複雑な状態を持つオブジェクトの設計はしないと思うのであんまり使わない図だと思います。 組み込み系だとデバイスの動作状況により振る舞いが変わったりするのでよく使うのかもしれません。
上の状態遷移図は次のPlantUMLの記述で生成しました。
@startuml state "公開中" as published { state "募集中" as recruiting state "募集終了" as closed recruiting --> closed closed --> recruiting } state "非公開" as private [*] --> private private --> published published --> private published --> [*] private --> [*] @enduml
タイミング図
多分、電子回路の設計などをするときに有用な図なのだと思うのですが、使ったことがないのでよくわからないです。 「タイミング図は現在作成中です。必要な機能があれば提案してください」とのことなので今後、書き方が変わっていくかもしれないですね。
UML だけでない PlantUML
PlantUML という名称なので描けるのは UML だけかなと思うのですが、そうではありません。 UML にはないけれど、システム開発でよく使われる PlantUML がサポートする図を紹介します。
ER図
データベースのテーブル構成を表す図です。
Rails の様なO/R マッパーを使うフレームワークで開発しているシステムではクラス図 ≒ ER 図なのであんまり使わなくなっているかもしれません。
上の ER 図は次のPlantUMLの記述で生成しました。
@startuml entity regions { code --- name description } entity prefectures { code --- name description } entity cities { code --- name description } regions ||--|{ prefectures prefectures ||--|{ cities @enduml
ガントチャート
ガントチャートも書けます。
上のガントチャートは次のPlantUMLの記述で生成しました。
@startgantt language ja saturday are closed sunday are closed 2022-02-11 is closed Project starts 2022-02-01 -- プロトタイピング -- [プロトタイプを作成] lasts 2 days and starts 2022-02-01 [プロトタイプを評価] lasts 2 days and starts at [プロトタイプを作成]'s end -- 本開発 -- [設計] lasts 2 days and starts 2022-02-07 [実装] lasts 5 days and starts at [設計]'s end [テスト] lasts 5 days and starts 2022-02-15 [リリース] happens at [テスト]'s end @endgantt
最近ではどちらかというと嫌われているようですが、実際にはウォーターフォールプロセスが嫌われていて、それに付き物のガントチャートも嫌われているのかなと思います。 比較的短期だけど関係者が少なくないプロジェクトでは進行状況を把握すのに便利だと思うんですけどね。
WBS図(作業分解図)
比較的大きくて工程が多岐に渡るプロジェクトではタスク分解が重要だったりします。 WBS(Work Breakdown Structure) はプロジェクトを理解し管理する上で、プロジェクトの各工程を各担当者の作業レベルまで展開し木構造に整理した図です。
箇条書き+α な記述を図化してくれるので使いようによっては便利だと思います。
組織図を描くのにも使えますね。
上のWBS図は次のPlantUMLの記述で生成しました。
@startwbs + 新規サイト構築 ++ サイト設計 +++ サービス名検討 ++++ アイコンデザイン +++ 運用フロー検討 ++++ コンテンツ更新 +++ サイトマップ作成 ++++ サービスページ ++++ 管理画面 ++ ソフトウェア開発 +++ 設計 ++++ アーキテクチャ設計 ++++ API設計 ++++ クラス設計 +++ 実装 +++ テスト ++ インフラ構築 +++ 設計 +++ サーバ構築 ++++ 開発サーバ ++++ 本番環境 +++ CI/CDパイプライン構築 ++ テスト +++ 機能テスト +++ 負荷テスト +++ 障害テスト @endwbs
Network diagram (nwdiag)
ネットワーク構築を含むシステム構築だとネットワーク図も書くと思います。 ケーブリングを含むと工事も発生しますし、関係者の認識合わせが重要です。 ということで次の様にネットワーク図を描くことができます。
上のネットワーク図は次のPlantUMLの記述で生成しました。
@startuml nwdiag { network dmz { address = "210.x.x.x/24" web01 [address = "210.x.x.1"]; web02 [address = "210.x.x.2"]; } } @enduml
大きい会社で社内ネットワークを管理されている方にも有用かと思います。
マインドマップ
マインドマップも書けます。
例えば次の様なテキストが下のような図になります。
箇条書きで整理したアイデアなどをさっと図化できそうで意外と便利かもと思いました。
上のマインドマップは次のPlantUMLの記述で生成しました。
@startmindmap +[#White] いこーよ ++[#Orange] お出かけ施設 +++ 動物園 +++ 水族館 +++ 遊園地 ++++ テーマパーク ++++ 屋内遊園地 +++ etc ++[#Orange] イベント +++ オンライン +++ オフライン ++++ 動物ふれあい ++++ コンサート ++++ アウトドア ++++ etc --[#Orange] 記事 --- 子育て --- 健康病気 --- 教育しつけ @endmindmap
標準ライブラリ
現在のシステムは AWS のクラウドサービスを始め様々なサービスを利用して構築されます。その様なシステムを図示する場合、クラウドサービスのアイコンなどを入れたくなりますよね。 PlantUML ではそれらが標準ライブラリとして用意されています。
主なところでは次の様な標準ライブラリが公開されています。
- awslib: AWS の各種サービスアイコン
- kubernetes: k8s の各種リソースアイコン
- logos: Gil Barbara's logosで公開されている各種サービスのロゴ(ネットサービスやクレジットカードなど)
これらを使ったシーケンス図の例が次の図です。
上のシーケンス図は次のPlantUMLの記述で生成しました。
@startuml !include <logos/github-icon> !include <logos/slack> !include <awslib/AWSCommon> !include <awslib/Mobile/APIGateway> !include <awslib/Compute/Lambda> !include <awslib/DeveloperTools/CodeBuild> !include <awslib/Containers/ElasticKubernetesService> actor Developper as dev participant "<$github-icon>" as github <<webhook>> #ffffff APIGatewayParticipant(endpoint, WebhookEndPoint,) LambdaParticipant(test_trigger,TestTrigger,) CodeBuildParticipant(codebuild,TestRunner, Rspecを実行) LambdaParticipant(test_reporter,TestReporter,) participant "<$slack>" as slack #ffffff dev -> github: Pull RequestにPush github -> endpoint: webhook endpoint -> test_trigger: invoke test_trigger -> codebuild: startBuild codebuild -> test_reporter: EventBridge経由でトリガー test_reporter -> slack: 結果を通知 @enduml
https://plantuml.com/ja/stdlibには他の標準ライブラリも紹介されています。
まとめ
このエントリではシンプルな例を示しましたが、色をつけたり、ノートを付けたり、リンクを張ったりと PlantUML はまあまあ高い表現力も持っています。
使い方は公式サイトに詳しく説明されています。
また、Real World PlantUMLには色々な例を見ることができます。
PlauntUML のメリット・デメリットをまとめると次の様になるかと思います(UML のメリット・デメリットではありません)。
- メリット
- テキストだけで UML がかける
- 図の要素をは自動レイアウトしてくれる
- デメリット
- オブジェクトが多すぎると思うようにレイアウトできず見ずらい
メリットで大きいのはなんと言ってもテキストで書けることです。テキストということは Git でバージョン管理も可能ということです。
一方、デメリットがクリティカルといえばクリティカルですが、要素が少ないうちは PlantUML の機能( down、up、right、left による指定など)でまあまあ見やすく配置できます。
要素が多くなってくるとそれも辛いですが、そもそもきれいにレイアウトしたところで要素が多いと見づらくなるかと思うのでシステム内での問題領域毎に分割して見やすい大きさにすればいいのではと思います。
見やすくレイアウトすることが重要な場合には diagrams.netなどの利用を検討してもいいかもしれません5。
文章で説明するよりも図を見せたら一発で理解できる、認識が合うことは多いです。 チーム内での認識の共有を助ける図を描くのに PlantUML は便利なツールの 1 つだと思います。
最後に
アクトインディではエンジニアを募集しています。