PlantUML - クラス図
クラス図は Doxygen や CASE ツール等でも生成できますが、 パッケージなども書けますし、大まかな構成を記述する際に役に立ちます。

@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

クラスの関係と線種
クラス間の関係と線種は次のようになります。記号 | 線種 | 関係 |
---|---|---|
-- | 実線 | 関連 |
<-- | 矢印 実線 | |
<|-- | 白抜き矢印 実線 | 汎化 |
<|.. | 白抜き矢印 破線 | 実現 |
o-- | 白抜き菱形 実線 | 集約 |
*-- | 黒塗り菱形 実線 | コンポジション、合成 |
<.. | 矢印 破線 | 依存 |
.. | 破線 | (ノートで使用されます) |
デフォルトはシーケンス図で、シーケンス図にない記号がつかわれたり、 次章のクラス定義があった場合にクラス図となります。
- 関連
-
クラス間になんらかの関連がある関係です。一番意味の広い関係です。
矢印は誘導可能性です。 矢印の方向にのみ関連があります。 実装レベルでいえば、ヘッダーをインクルードする必要があるかといった関係になります。
矢印がない場合は方向が不明であるか、双方向に関連しています。
@startuml{plantuml_class_assocation.png} Control -- View Control --> Model @enduml
- 汎化と実現
-
汎化は抽象化ともいい、継承(is-a)関係の逆になります。
汎化も関連の一種です。 継承の方がわかりやすいですが、 基底クラスは派生クラスを関知しないため、矢印の向きにあう汎化となります。
基底クラスがインターフェースや抽象クラスで、 派生クラスがその振る舞いを実装する場合、特に実現といいます。
@startuml{plantuml_class_is_a.png} "図形" <|-- "四角形" : 汎化 Comparable <|.. ComplexNumber : 実現 @enduml
- 集約と合成
-
集約は全体と部分といった包含(has-a)関係です。
合成は結合の強い集約で、全体と部品といった関係になります。
@startuml{plantuml_class_has_a.png} "駐車場" o-- "自動車" : 集約 "車" *-- "タイヤ" : 合成 "車" *--> "エンジン" : 合成(矢印付き) @enduml
- 依存
- 変更すると他方にも変更が生じるような関係です。
@startuml{plantuml_class_depend.png} "残量メーター" ..> "燃料タンク" : 依存 @enduml
線の長さと矢印の向き
例えば関連の矢印の場合 <-, <--, <--- というように - や . はいくつ書いてもかまいません。この長さ(文字数)はレイアウトの向きと相対的な長さに使われます。
文字数 | 向き |
---|---|
1 | 横 |
2 | 縦 |
@startuml{plantuml_class_linelength.png} Foo - Bar1 Foo -- Bar2 Foo --- Bar3 @enduml

また、 -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

多重度
関係の多重度を記述する場合には関係の前後に記述します。クラス名 "多重度" 線種 "多重度" クラス名 [: ラベル]
@startuml{plantuml_class_multi.png} Car "1" *-- "4" Tire "車" "1" o-- "0..*" "駐車場" : 1 対 多 @enduml

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

メンバーの追加
属性(メンバー変数)やメソッド(メンバー関数)は : を使って追加するか、クラス定義時に {} 内に記述します。クラス名 : メンバー
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

可視性
private などの可視性の指定はメンバーの前に記号を付けます。記号 | 可視性 |
---|---|
- | private |
# | protected |
~ | package private |
+ | public |
@startuml{plantuml_class_visibility.png} class Foo { -m_field #method1() ~method2() +method3() } @enduml

可視性のアイコンを表示したくない場合には 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

特殊クラスの定義
クラス定義は 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

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

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

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

テンプレート(ジェネリック)
テンプレート(ジェネリック)クラスは < > を使って表現します。@startuml{plantuml_class_template.png} class HashMap<Key:Class, Value:Class> { Value &getValue(const Key &key) } HashMap *- Element @enduml

パッケージ
パッケージ定義
パッケージを記述する場合には 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

パッケージスタイル
パッケージのスタイルはデフォルトのフォルダースタイルだけでなく、 ステレオタイプで指定することによって、形状を変えることができます。@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


ネームスペース
同じ名前のクラス名をネームスペースで分けて定義することはあると思います。 これをクラス図で実現するには 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

ノート
クラスに対するノート
クラスに対してノート(コメント)を付けることができます。note position of クラス : コメント
クラス定義position には以下のキーワードのいづれかを指定します。
note 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

この方法では表示できない方向にノートを付けるとエラー終了してしまいます。 次の方法でノートを付ける方がお勧めです。
関係を使ったノート
別名をつけてノートの要素を作り、 それをクラスにリンクさせることによってコメントをつけます。@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

リンクへのノート
クラスの関係の記述の直下にノートを書くと関係のリンクへのノートとなります。クラス関係の記述
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

オブジェクト図
オブジェクト図はクラス図とほぼ同じです。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

パッケージ図
PlantUML にはパッケージ図は特に用意されていません。 しかし、空のパッケージやパッケージ間のリンクもできるため、 クラス図で代用することができます。ただし、パッケージ - クラス間のリンクはできません。
@startuml{plantuml_class_package_diagram.png} package 検索処理 end package package 描画処理 { } 検索処理 .> 描画処理 : <<import>> package "入出力処理" as io { } 検索処理 ..> io : <<access>> package データベース { } io +-- データベース @enduml

参考
このページの記述には以下のサイトを参考にさせていただきました。- PlantUML の本家のページ
- UML 超入門_第 2 章
- UML クラス図: ガイドライン
- 連載:【改訂版】初歩の UML 第 5 回
- パッケージ図(Package Diagram) - UML入門 - IT専科