PlantUML - クラス図

PlantUML でのクラス図の記法についての解説です。
クラス図は Doxygen や CASE ツール等でも生成できますが、 パッケージなども書けますし、大まかな構成を記述する際に役に立ちます。
  1. クラスの関係
  2. クラス定義
  3. パッケージ
  4. ノート
  5. オブジェクト図
  6. パッケージ図
  7. 参考
Class diagram sample
@startuml{plantuml_class_sample.png}
title <size:18> クラス図 のサンプル </size>
class Canvas
package Geometry
abstract Figure {
    #{static} const size_t ParseBufferSize = 256
    +{abstract} size_t getPointsNum()
    +{static} Figure *ParseString(const char *str)
}

Figure "0..*" o- "1" Canvas : 集約

Figure <|-- Rect : 汎化
Figure <|-- Polygon
Rect <|-- Ellipse

end package
@enduml
タイトル(title)HTML タグ に関してはシーケンス図の説明を参照してください。

クラスの関係

クラスの関連は以下の形式で書きます。
クラス名 線種の記号 クラス名 [: ラベル]
クラス名に英数字以外を使いたい場合は "(ダブルクオート) で囲みます。
日本語の場合は " がないとうまく表示されない場合があるので、囲っておいた方が安全です。
@startuml{plantuml_class_relation.png}

ClassA -- "Class B"
"クラスC" -- "Class\nD" : 関係

@enduml
Relation sample

クラスの関係と線種

クラス間の関係と線種は次のようになります。
記号 線種 関係
-- 実線 関連
<-- 矢印 実線
<|-- 白抜き矢印 実線 汎化
<|.. 白抜き矢印 破線 実現
o-- 白抜き菱形 実線 集約
*-- 黒塗り菱形 実線 コンポジション、合成
<.. 矢印 破線 依存
.. 破線 (ノートで使用されます)
PlantUML では UML のどの図を使うかの指定はありません。
デフォルトはシーケンス図で、シーケンス図にない記号がつかわれたり、 次章のクラス定義があった場合にクラス図となります。

関連
クラス間になんらかの関連がある関係です。一番意味の広い関係です。

矢印は誘導可能性です。 矢印の方向にのみ関連があります。 実装レベルでいえば、ヘッダーをインクルードする必要があるかといった関係になります。
矢印がない場合は方向が不明であるか、双方向に関連しています。
@startuml{plantuml_class_assocation.png}

Control -- View
Control --> Model

@enduml
Assocation sample
汎化と実現
汎化は抽象化ともいい、継承(is-a)関係の逆になります。
汎化も関連の一種です。 継承の方がわかりやすいですが、 基底クラスは派生クラスを関知しないため、矢印の向きにあう汎化となります。

基底クラスがインターフェースや抽象クラスで、 派生クラスがその振る舞いを実装する場合、特に実現といいます。
@startuml{plantuml_class_is_a.png}

"図形" <|-- "四角形" : 汎化
Comparable <|.. ComplexNumber : 実現

@enduml
is a sample
集約と合成
集約は全体と部分といった包含(has-a)関係です。
合成は結合の強い集約で、全体と部品といった関係になります。
@startuml{plantuml_class_has_a.png}

"駐車場" o-- "自動車" : 集約
"車" *-- "タイヤ" : 合成
"車" *--> "エンジン" : 合成(矢印付き)

@enduml
has a sample
依存
変更すると他方にも変更が生じるような関係です。
@startuml{plantuml_class_depend.png}

"残量メーター" ..> "燃料タンク"  : 依存

@enduml
depend sample

線の長さと矢印の向き

例えば関連の矢印の場合 <-, <--, <--- というように - や . はいくつ書いてもかまいません。
この長さ(文字数)はレイアウトの向きと相対的な長さに使われます。
文字数 向き
1
2
@startuml{plantuml_class_linelength.png}

Foo - Bar1
Foo -- Bar2
Foo --- Bar3

@enduml
linelength sample

また、 -position- と書く事によって、関係の方向を明示的に指定することもできます。 position には以下のキーワードが使えます。
方向 キーワード
up, u
down, d, do
left, l, le
right, r, ri
@startuml{plantuml_class_line_direction.png}

Foo -up-> 上
Foo -do-> 下
Foo -le-> 左 
Foo -ri-> 右 

@enduml
Line direction sample

多重度

関係の多重度を記述する場合には関係の前後に記述します。
クラス名 "多重度" 線種 "多重度" クラス名 [: ラベル]
@startuml{plantuml_class_multi.png}

Car "1" *-- "4" Tire
"車" "1" o-- "0..*" "駐車場" : 1 対 多

@enduml
Multiplicity sample

クラス定義

クラス定義は省略するできますが、 class キーワードで明示的に記述することもできます。
シーケンス図と同様に色名の指定、別名(as)を付けることもできます。 ただし、この場合は "" で囲う必要があります。
@startuml{plantuml_class_define.png}
class Rect
class "Figure" as fig #E0FFFF

fig <|-- Rect

@enduml
Class define sample

メンバーの追加

属性(メンバー変数)やメソッド(メンバー関数)は : を使って追加するか、クラス定義時に {} 内に記述します。
クラス名 : メンバー
class クラス名 {
  メンバー
}
属性かメソッドはメンバーの () の有無で判断しています。
@startuml{plantuml_class_member.png}
class Node {
    size_t getElementNum()
    Element *getElement(size_t id)

    std::vector<Element*> m_elements
}
Element <|-- Node

Element: getName()

@enduml
Member sample

可視性

private などの可視性の指定はメンバーの前に記号を付けます。
記号 可視性
- private
# protected
~ package private
+ public
@startuml{plantuml_class_visibility.png}
class Foo {
    -m_field
    #method1()
    ~method2()
    +method3()
}
@enduml
Visibility sample
可視性のアイコンを表示したくない場合には skinparam で指定してください。

抽象(純粋仮想)関数とクラスメンバー

メソッドが抽象(純粋仮想)関数 の場合には {abstract} をつけます。
クラス変数やクラス関数の場合には {classifier} または {static} で指定します。
@startuml{plantuml_class_abst.png}
class Figure {
    {abstract} size_t getPointsNum()
    {static} Figure *ParseString(const char *str)
    {static} const size_t ParseBufferSize = 256
}

@enduml
Abstract Static sample

特殊クラスの定義

クラス定義は class キーワードだけでなく、特殊な型(クラス)用のキーワードも用意されています。
キーワード
abstract, abstract class 抽象クラス
interface インターフェースクラス
enum 列挙型
@startuml{plantuml_class_specclass.png}
enum FigureType {
    FigureType_unknown=-1
    FigureRect
    FigurePolygon
    FigureEllipse
}

abstract Figure
class Rect
interface Comparable {
  {abstract} int compare(Comparable *other)
}

Figure <|-- Rect
Rect .|> Comparable 

@enduml
Special class sample

スポットとステレオタイプ

シーケンス図と同様にクラス定義の後にステレオタイプを書く事ができます。
また、ステレオタイプで C, I, A, E 以外のスポットを指定することができます。
class クラス名 <<(スポット文字, 色) [ステレオタイプ名]>>
@startuml{plantuml_class_spot.png}
class System << (S,#FF7700) Singleton >>
class Date << (D,violet) >>

@enduml
Spot sample

ロリポップ

インターフェースクラスを実現する場合で、 インターフェイスを提供しているということを強調するために、 ロリポップ(棒付きキャンディー)で省略表記することがあります。
PlantUML でロリポップとして表示するには、関係の線種に ()-- を使います。

@startuml{plantuml_class_lollipop.png}

Comparable ()-- RationalNumber

@enduml
Lollipop sample

ただし、インターフェースを介して利用するクラスとインターフェース間の関係ではロリポップを使ったリンクはできません。
Lollipop sample

テンプレート(ジェネリック)

テンプレート(ジェネリック)クラスは < > を使って表現します。
@startuml{plantuml_class_template.png}

class HashMap<Key:Class, Value:Class> {
    Value &getValue(const Key &key)
}

HashMap *- Element

@enduml
Template sample

パッケージ

パッケージ定義

パッケージを記述する場合には package キーワードを使用します。
package パッケージ名 {
  クラス定義や関係
}
package パッケージ名
  クラス定義や関係
end package
クラス定義と同様に色指定なども使用できます。
@startuml{plantuml_class_pkgdef.png}

package "Classic Collections" #DDDDDD {
  Object <|-- ArrayList
}

package net.sourceforge.plantuml
  Object <|-- Demo1
  Demo1 *- Demo2
end package

@enduml
Package define sample

パッケージスタイル

パッケージのスタイルはデフォルトのフォルダースタイルだけでなく、 ステレオタイプで指定することによって、形状を変えることができます。
@startuml{plantuml_class_pkgstyle1.png}

package node <<Node>> {
  class Class1
}

package rect <<Rect>> {
  class Class2
}

package "folder (default)" <<Folder>> {
  class Class3
}

@enduml
@startuml{plantuml_class_pkgstyle2.png}

package frame <<Frame>> {
  class Class4
}

package cloud <<Cloud>> {
  class Class5
}

package database <<Database>> {
  class Class6
}

@enduml
Package style sample 1 Package style sample 2

ネームスペース

同じ名前のクラス名をネームスペースで分けて定義することはあると思います。 これをクラス図で実現するには namespace キーワードを使用します。 namespace キーワードは package と同じようなスタイルで記述します。

ネームスペースをまたいだクラス関係を記述する場合には . (ピリオド) でつないで "ネームスペース名"."クラス名" といった形式でクラスを指定します。
@startuml{plantuml_class_namespace.png}

abstract class AbstractPerson

namespace net.dummy #DDDDDD
  .AbstractPerson <|-- Person
  'ネームスペース外のクラスは指定するには前に . 
  'つけていないとネームスペース内で新しいクラス要素を作る

  Meeting o-- Person
  
  .AbstractPerson <|- Meeting

end namespace

namespace net.foo {
  net.dummy.Person  <|- Person
  .AbstractPerson <|-- Person

  net.dummy.Meeting o-- Person
}

AbstractPerson <|-- net.auto.Person
'namespace の定義なしで作成

@enduml
Namespace sample

ノート

クラスに対するノート

クラスに対してノート(コメント)を付けることができます。
note position of クラス : コメント
クラス定義
note position : コメント
position には以下のキーワードのいづれかを指定します。
  • top
  • bottom
  • left
  • right
@startuml{plantuml_class_noteclass.png}
class Bar
note right
  Bar に対する
  クラス
end note

Foo - Bar

note top of Foo : Foo に対する\nノート
'right を指定するとエラー

@enduml
Notes for class sample
この方法では表示できない方向にノートを付けるとエラー終了してしまいます。 次の方法でノートを付ける方がお勧めです。

関係を使ったノート

別名をつけてノートの要素を作り、 それをクラスにリンクさせることによってコメントをつけます。
@startuml{plantuml_class_noterelation.png}
abstract Object
Object <|--- ArrayList

note "Object に対するノート" as NO
Object . NO

note as N2
  複数の対象に
  関連づけられたノート
end note
Object .. N2
N2 .. ArrayList

note "対象が指定されていない\n フローティングノート" as NF
'使わない場合でも別名をつけないと解析エラー

@enduml
Notes by relation sample クラスの関係の記述の直下にノートを書くと関係のリンクへのノートとなります。
クラス関係の記述
note [position] on link : コメント
@startuml{plantuml_class_notelink.png}

class Dummy
Dummy --> Foo : A link
note on link #red: 赤い背景色のノート

Dummy --> Bar : Another link
note right on link #E0FFFF
    右側に配置した
    ノート
end note

@enduml
Notes for link sample

オブジェクト図

オブジェクト図はクラス図とほぼ同じです。
class の代わりにobject を使うとオブジェクト図となります。 ただし、 ブロックによる定義では英数字しか使えないため、 それ以外の文字を使いたい場合は一度 as で別名を付けた後、メンバーを追加する必要があります。
@startuml{plantuml_class_object.png}

object foo {
    id = 1234
    name = "Alice"
}

object "<u>bar:Bar</u>" as bar
bar : id = 4321
bar : name = "Bob"

@enduml
Object diagram sample

パッケージ図

PlantUML にはパッケージ図は特に用意されていません。 しかし、空のパッケージパッケージ間のリンクもできるため、 クラス図で代用することができます。
ただし、パッケージ - クラス間のリンクはできません。
@startuml{plantuml_class_package_diagram.png}

package 検索処理
end package

package 描画処理 {
}

検索処理 .> 描画処理 : <<import>>

package "入出力処理" as io {
}

検索処理 ..> io : <<access>>

package データベース {
}

io +-- データベース

@enduml
Package diagram sample

参考

このページの記述には以下のサイトを参考にさせていただきました。
関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

No title

初めまして、情報処理の勉強をしている者です。

クラス図の書き方、とても勉強になります!

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
33位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

04月 | 2017年05月 | 06月
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。