BIGLOBEの「はたらく人」と「トガッた技術」

成長するドメインモデリングと相性抜群!PlantUMLの紹介

f:id:biglobe-editor2:20220316111029j:plain

ドメインモデルを図で理解するのに便利なPlantUML。レイアウト調整のノウハウと合わせてその魅力を紹介します。

はじめに

基盤本部(開発部門)の宮下です。

BIGLOBEではドメイン駆動設計(Domain Driven Design:DDD)を実践しています。 DDDではドメインモデルを育てていき、継続的にソフトウェアの価値を高めていくことが重要となります。

ドメインモデルとは、業務的な関心ごと(=ドメイン)の問題を解決するために表現するものです。そんなドメインモデルをみんなで設計するときに、BIGLOBEではPlantUMLというツールを使っています。キーボードだけでサクッと図を描けてしまう優れものです。

この記事では、PlantUMLに詳しくない方はもちろん、PlantUMLでもっと見やすい図を描きたいな!と思っている方向けのノウハウを紹介したいと思います。

対象読者

  • PlantUMLに詳しくない方
  • PlantUMLでもっと見やすい図を描きたいと思っている方

PlantUMLとは

PlantUMLはUML(Unified Modeling Language)をはじめとした図を作成するのに便利で商用利用可能なフリーツールです。
以下のような複雑な図も作成できます。

上記の図以外にも様々な図が作成できます。PlantUMLの日本語ページに例があるので、参考にしてください。

次に、個人的に感じるPlantUMLのメリットとデメリットを挙げます。

メリット

  1. テキストベースで記述できる
    これがPlantUMLを利用するモチベーションとなる一番大きなメリットかと思います。バージョン管理システムで変更履歴を管理でき、メンテナンスがしやすいです。ドメインモデルを継続的に育てていくDDDと相性が良いのかなと思います。
  2. プラグインを入れると編集しながらリアルタイムで図をプレビューできる
    IntelliJ IDEAVisual Studio Code等、主要なIDEやテキストエディタでプラグインが公開されています。プレビューに即時編集内容が反映されるので、効率的に編集作業ができます。プレビューを見せながら議論をして修正するという使い方もできるので、コミュニケーションを取る際にも有用です。

※業務利用の場合はPlantUMLのオンラインサーバーを使用しないようにしています。

デメリット

  1. レイアウト調整に工夫が必要
    PlantUMLでは図のレイアウトを自動で行ってくれますが、思うようにいかないことが多々あります。後述するテクニックを使えばある程度きれいに配置できますが、細かな調整をしたい場合には向かないです。

レイアウトを調整するためのテクニック

デメリットとして、レイアウト調整に工夫が必要と挙げましたが、ここでレイアウト調整するためのちょっとしたテクニックを紹介します。

  1. -. の数で調整

    f:id:biglobe-editor2:20220316123440p:plain

    @startuml
    
    package Horizontal {
        class A {}
        class B {}
        class C {}
        class D {}
        C . D
        A - B
    }
    
    package Vertical {
        class G {}
        class H {}
        class E {}
        class F {}
        E -- F
        G .. H
    }
    
    package LongDependencyLine {
        class I {}
        class J {}
        class K {}
        class L {}
    
        I --- J
        I ---- K
        I ..... L
    }
    
    @enduml
    
    • -.が1つの場合
      水平方向に依存関係の線が伸びます。
    • -.2つの場合
      垂直方向に依存関係の線が伸びます。
    • それ以上増やした場合
      線を長さを変えられます。
  2. 要素や依存関係を定義する順番を変える
    1.のソースコードを見て違和感を持った方がいるかと思いますが、要素や依存関係を定義した順番で配置が変わることがあります。 ソースコードを自然な順番で定義するよう修正してみましょう。

    @startuml
    
    package Horizontal {
        class A {}
        class B {}
        class C {}
        class D {}
        A . B
        C - D
    }
    
    package Vertical {
        class E {}
        class F {}
        class G {}
        class H {}
        E -- F
        G .. H
    }
    @enduml
    

    すると、図はこのようになります。

    f:id:biglobe-editor2:20220316123823p:plain

    配置が左から (C - D), (A - B), (G - H), (E - F)となり、違和感がありますよね。 このように配置に納得がいかない場合は、要素や依存関係の定義順を見直すのもありなのかもしれません。

  3. 依存関係がある要素を左右入れ替える
    以下の例を見てください。

    f:id:biglobe-editor2:20220316123926p:plain

    ソースコードはこちらです。

    @startuml
    
    class Fruit {}
    class Orange {}
    class Banana {}
    class Apple {}
    
    Fruit <|-- Orange
    Fruit <|-- Banana
    Apple --|> Fruit
    
    @enduml
    

    図の配置とソースコードの関係を見ると以下のようになっています。

    • Banana, Orange
      • 図の配置:Fruitよりも下
      • ソースコード:Fruitが左、Banana, Orangeが右
    • Apple
      • 図の配置:Fruitよりも上
      • ソースコード:Appleが左、 Fruitが右

    要素を左右入れ替えるだけで、配置が変わったことが分かります。
    また、1.と関連しますが、-, .の数にも関係していて以下のようになります。

    • -, .の数が1つの場合
      • 左側に定義した要素:左側に配置
      • 右側に定義した要素:右側に配置
    • -, .の数が2つの場合
      • 左側に定義した要素:上側に配置
      • 右側に定義した要素:下側に配置
  4. 依存関係の方向を明示的に指定する
    依存関係を結ぶ線の間にup, down, left, rightのような指定が可能です。
    u, d, l, rのように省略も可能です。

    f:id:biglobe-editor2:20220316124017p:plain

    @startuml
    
    class Center {}
    class Up {}
    class Left {}
    class Right {}
    class Down {}
    
    Center -up- Up
    ' 垂直方向の場合、線を伸ばすことも可能
    Center -down--- Down
    Center -left- Left
    
    Center -right- Right
    
    @enduml
    
  5. [hidden]の使用
    依存関係はないけれど、配置上どうにかしたい場合は[hidden]が使えます。
    まずは以下の例を見てください。

    f:id:biglobe-editor2:20220316124108p:plain

    昆虫類(Insects)、 カブトムシ(Beatle) がAnimalと同階層に並んでいて気持ち悪いですね...
    適切な配置にしたいため、[hidden]を使うように修正します。

    f:id:biglobe-editor2:20220316124202p:plain

    @startuml
    
    class Animal {}
    
    ' 哺乳類
    class Mammalian {}
    note left of Mammalian: 哺乳類
    ' 昆虫類
    class Insects {}
    
    class Dog {}
    class Cat {}
    class Monkey {}
    class Beatle {}
    
    Animal <|-- Mammalian
    Mammalian <|-- Dog
    Mammalian <|-- Cat
    Mammalian <|-- Monkey
    
    Animal <|-[hidden]- Insects
    Insects <|-[hidden]- Beatle
    
    @enduml
    

    いかがでしょうか?今度は昆虫類(Insects)、 カブトムシ(Beatle)が適切な階層に配置されました。 階層構造になっているようなものを図示したいときに有効なテクニックです。

    ...昆虫類も動物の一種だし、カブトムシは昆虫類でしょうが!依存関係を定義していないなんて!というツッコミはやめてください(笑)



さて、5つほどレイアウトのテクニックを紹介しましたが、ここで元も子もないことを言います。
レイアウト調整はほどほどにしてください(笑)

なぜならば、きれいな図を作ることが目的ではなく、図を使って議論したり、頭を整理したりすることが本来の目的となるはずだからです。

また、PlantUMLでレイアウトを細かく制御するのは難しいですし、あまりおすすめしません。ある程度のところで割り切るのが良いかと思います。

まとめ

PlantUMLの概要とちょっとしたテクニックを紹介しました。繰り返しになりますが、DDDを実践するには非常に有用なツールですし、ちょっとした図を作りたい場合でも便利なツールです。 ぜひPlantUMLを活用してみてください。

BIGLOBEでは、DDDを活用したサービス・アーキテクチャの設計・開発に取り組んでいます。DDDを実践してドメインモデルを継続的に成長させるために、ツールにもこだわりながら色々な工夫をしています。 興味のある方はぜひカジュアル面談にいらしてください。

hrmos.co

※ UML、Unified Modeling Languageは、Object Management Group, Inc.の米国及びその他の国における登録商標または商標です。

※ IntelliJ、IntelliJ IDEAは、JetBrains s.r.o.の商標または登録商標です。

※ Visual Studioは、Microsoft Corporation の、米国およびその他の国における商標または登録商標です。