真面目に PlantUML (3) : クラス図
今回はクラス図(class diagram)について。 クラス図はシステムの構成要素であるクラスを定義しクラス同士の関係を表現したものである。
目次
- PlantUML のインストール
- シーケンス図
- クラス図 ← イマココ
- 実体関連図
クラスの定義
まずはクラスの定義から。
クラスはひとつの「名前」,0個以上の「属性」,0個以上の「操作」で構成され,以下のように表す。
@startuml
hide circle
class "Class Name" as Class {
{field} Attributes
{method} Operations
}
@enduml
抽象クラスの場合は「名前」をイタリック(または斜体)で表す。
PlantUML では abstract
を付けることで抽象クラスとして扱われる。
@startuml
hide circle
abstract class "Abstract Class" as Class1
abstract class "Interface Class" as Class2 <<interface>>
@enduml
<<interface>>
はステレオタイプ(stereotype)と呼ばれているもので,ここではクラスの種別を表している。
なお PlantUML ではアイコンを使ってクラス種別を表現できる。
@startuml
show circle
class ImplementClass
abstract class AbstractClass
interface InterfaceClass
enum Enum {
ONE
TWO
THREE
}
annotation Annotation
class CustomClass << (S,orchid) custom >>
@enduml
最後の CustomClass ではアイコンをカスタムで指定している。
属性(attribute),操作(operation),可視性(Visibility)
UML ではクラス内の「属性」を以下のように表記する。
可視性 名前:型 [=初期値] {制約条件}
「操作」も同じように
可視性 名前([引数の名前:引数の型[, ...]]) : 戻り値の型
と表記する。
「可視性」は属性・操作にアクセスできるスコープを示し,以下の記号で表す。
可視性 | スコープ |
---|---|
+ |
Private 自クラスでのみアクセス可能 |
- |
Public 全てのパッケージ・クラスでアクセス可能 |
# |
Protected 自クラスとその派生クラスでアクセス可能 |
~ |
Package Protected 同じパッケージ内でアクセス可能 |
PlantUML では以下のように記述する。
@startuml
hide circle
skinparam classAttributeIconSize 0
class ClassName {
{field} + publicField : String = "string" {read only}
{field} - privatefield : int
{field} # protectedfield : double
{field} ~ protectedfieldInPackage : Object
{method} + publicMethod(s : String, v : int) : void
{method} - privateMethod() : int
{method} # protectedMethod() : double
{method} ~ protectedMethodInPackage() : Object
}
@enduml
さらに classAttributeIconSize
を指定して可視性の部分をアイコン化することもできる。
@startuml
show circle
skinparam classAttributeIconSize 10
class ClassName {
{field} + publicField : String = "string" {read only}
{field} - privatefield : int
{field} # protectedfield : double
{field} ~ protectedfieldInPackage : Object
{method} + publicMethod(s : String, v : int) : void
{method} - privateMethod() : int
{method} # protectedMethod() : double
{method} ~ protectedMethodInPackage() : Object
}
@enduml
クラス変数,クラス・メソッド
クラス変数やクラス・メソッドはアンダーラインで表す。
PlantUML では static
または classifier
を付けることでクラス変数やクラス・メソッドであることを示す。
@startuml
hide circle
skinparam classAttributeIconSize 0
class ClassName {
{classifier} {field} + staticField : String = "string" {read only}
{classifier} {method} + staticMethod() : void
}
@enduml
抽象メソッド
抽象メソッドはイタリック(または斜体)で表す。
PlantUML では abstract
を付けることで抽象メソッドであることを示す。
@startuml
hide circle
skinparam classAttributeIconSize 0
class ClassName {
{abstract} {method} + abstractMethod() : void
}
@enduml
PlantUML はクラス・メンバについてかなりアドホックに記述できるため,とりあえずメモ書きを残しておいて,あとから厳密に決めていくのがいいかも知れない。
クラス間の関係
クラス間の関係はクラス同士を線で繋いで表すが,線(矢印)の種類によって関係の違いを表現できる。
@startuml
hide circle
Class01 <|-- Class02 : Generalization
Class03 <|.. Class04 : Realization
Class05 <.. Class06 : Dependency
Class07 -- Class08 : Association
Class09 o-- Class10 : Aggregation
Class11 *-- Class12 : Composition
@enduml
それぞれの意味は以下の通り
種別 | 意味 |
---|---|
Generalization | 汎化 いわゆる is-a 関係がある |
Realization | 実現 interface 型のような抽象クラスとの汎化関係がある |
Dependency | 依存 矢印の相手に対して依存関係がある |
Association | 関連 クラス間で関連がある |
Aggregation | 集約 関連の一種で,全体-部分の関係がある |
Composition | コンポジション 集約の一種だが片方のみでは成り立たないような強い関係を示す |
多重度(Multiplicity)
関連する2つのクラスについて多重度を設定する。 たとえば Class A と Class B の間に 1:多 の関係があるなら
@startuml
hide circle
hide empty members
class "Class A" as A
class "Class B" as B
A "1" -- "*" B : Association
@enduml
などと記述する。 多重度表記とその意味は以下の通り。
多重度 | 意味 |
---|---|
1 |
1つのみ |
0,1 |
ゼロまたは1つ |
0..n or n |
ゼロ以上多数 |
1..n |
1以上多数 |
* |
n と同じ |
クラス図を使った設計では多重度の決定が最優先
クラス図を使って設計を行う場合は多重度を最優先で考える。 すなわち
- システムに必要なクラスを列挙する
- 関連のあるクラスを線で繋ぐ
- 繋がっているクラスについて多重度を決定する
- クラスの種別を決定する
- クラス・メンバを検討する
という順番で考えていくとよいだろう。