PlantUMLでクラス図を描く
クラス図の例_
マーチン・ファウラー著 UMLモデリングのエッセンス 第3版 図3.1をPlantUMLで描くと以下のようになる。
上記のクラス図は以下のPlantUML記法で生成される。
- Fig3.1.puml(テキストファイル)
' マーチン・ファウラー著 UMLモデリングのエッセンス 第3版 図3.1
@startuml{Fig3.1.png}
title 簡単なクラス図
class "Order (注文)" as Order {
dateReceived: Date [0..1]
isPrepaid: Boolean [1]
number: String [1]
price: Money
dispatch()
close()
}
' 制約をノートとして記述する
note top of Order
{if Order.customer.getCreditRating is "poor" \n then Order.isPrepaid must be true}
end note
class "Order Line (注文明細)" as OrderLine {
quantity: Interger
price: Money
}
class "Product (製品)" as Product {
quantity: Interger
price: Money
}
class "Customer (顧客)" as Customer {
name [1]
address [0..1]
getCreditRating(): String
}
class "Corporate Customer (法人顧客)" as CorporateCustomer {
contactName
creaditRating
creditLimit
billForMonth(Integer)
remind()
}
class "Personal Customer (個人顧客)" as PersonalCustomer {
creditCardNumber
}
' 制約をノートとして記述する
note top of PersonalCustomer
{getCreditRating() == "poor"}
end note
Order "1" --> "*" OrderLine : " lineitems {ordered}"
Order "*" --> "1" Customer
OrderLine "*" --> "1" Product
CorporateCustomer --|> Customer
PersonalCustomer --|> Customer
CorporateCustomer "*" --> "0..1" Employee : salesRep
@enduml
クラスボックス_
もっともシンプルなクラス図_
もっともシンプルなクラス図は1つのクラスボックス(四角形)にクラス名を描いたもの。
上記のクラス図は以下のPlantUML記法で生成される。
- OnlyBox.puml(テキストファイル)
@startuml{OnlyBox.png}
title 単純なクラス図
class "クラス名" as OnlyClassBox
note bottom of OnlyClassBox
クラス名だけを記載する場合は、単純な四角形で良い。\n
PlantUMLの記法では属性欄と操作欄が必ず表示されてしまう。
end note
@enduml
属性と操作が記載されたクラス_
属性と操作も記述したクラスは以下のようになる。
- FullSet.puml(テキストファイル)
@startuml{FullSet.png}
title 属性と操作が記載されたクラス
class "クラス名" as FullSet {
属性(attribute)
書式: "可視性 属性名: 属性のタイプ 多重度 = デフォルト値 { プロパティ文字列 }"
例: "+ name: String [1] = "Untitled" {readOnly}"
"操作(operation)"()
書式: "可視性 操作名(パラメーターリスト) : 戻り値のタイプ {プロパティ文字列}"
例: "+ balanceOn (in date: Date = "2013/02/21") : Money"
}
note bottom of FullSet
属性および操作で必須なのは属性名および操作名のみ。\n
操作には必ずしも括弧"()"をつける必要はない。\n
ただし、PlantUMLの記法の場合、属性と操作の区別は括弧 "()" が\n
あるかないかで行っているため、操作には必ず括弧をつけなければいけない。
endnote
@enduml
プロパティ、属性と関連_
クラス図ではプロパティは属性あるいは関連で表現される。
関連_
- Association.puml(テキストファイル)
@startuml{Association.png}
title 関連
class "クラスA" as ClassA
class "クラスB" as ClassB
ClassA -right- ClassB
@enduml
プロパティを属性で表した場合_
上述の「簡単なクラス図」からクラスOrderとその関連クラスの一部を抜き出した図が以下のもの。
- PropertyAsAttribute.puml(テキストファイル)
@startuml{PropertyAsAttribute.png}
title プロパティを属性として表した場合
class "Order (注文)" as Order {
dateReceived: Date [0..1]
isPrepaid: Boolean [1]
number: String [1]
price: Money
dispatch()
close()
}
note bottom of Order
クラスOrderのプロパティは、dateReceived、isPrepaid、
number、price、lineitems。そのうち、lineitemsが関連で表記している。
残りは属性として表記している。
end note
class "Order Line (注文明細)" as OrderLine
Order "1" -right-> "*" OrderLine : " lineitems {ordered}"
@enduml
プロパティを関連で表した場合_
クラスOrderの属性として述べられているプロパティを関連として描くと以下のようになる。
- PropertyAsAssociation.puml(テキストファイル)
@startuml{PropertyAsAssociation.png}
title プロパティを関連として表した場合
class "Order (注文)" as Order
class "Order Line (注文明細)" as OrderLine
Order "1" -right-> "*" OrderLine : " lineitems {ordered}"
Order "*" -left-> "0..1" Date : "dateReceived"
Order --> "1" Boolean : "isPrepaid"
Order --> "1" String : "number"
Order --> Money : "price"
@enduml
誘導可能性矢印_
関連において、線分の片方だけ矢印がある関連が単方向関連、両方に矢印がある関連が双方向関連という。この矢印を誘導可能性矢印という。
- NavigabilityArrows.puml(テキストファイル)
@startuml{NavigabilityArrows.png}
title 誘導可能性矢印
class "クラスA" as ClassA
class "クラスB" as ClassB
class "クラスC" as ClassC
class "クラスD" as ClassD
ClassA -left- ClassB : 双方向 or \n 誘導可能性について考慮しない
ClassA <-right-> ClassC : 双方向関連
ClassA -down-> ClassD : 単方向関連
note bottom of ClassD
誘導可能性矢印の記載は1つの図においては
以下の方針のうちから1つしか選んではいけない。
1) そもそも矢印をつけない(誘導可能性について考慮しない)
2) 全部に矢印をつける
3) 全部に矢印をつけるが、双方向関連の場合は矢印なしにする
endnote
@enduml
汎化_
- Generalization.puml(テキストファイル)
@startuml{Generalization.png}
title 汎化
class "スーパータイプ" as SuperType
class "サブタイプ1" as SubType1
class "サブタイプ2" as SubType2
SuperType <|-- SubType1
SuperType <|-- SubType2
@enduml
依存関係_
- Dependency.puml(テキストファイル)
@startuml{Dependency.png}
title 依存関係
"クライアント" ..> "サプライア" : <<依存関係名(省略可)>>
class "クラスA" as ClassA
class "クラスB" as ClassB
class "クラスC" as ClassC
class "クラスD" as ClassD
ClassA ..> ClassB : <<use>>
ClassB ..> ClassC : <<call>>
ClassB ..> ClassD : <<call>>
note bottom of ClassC
依存関係は基本的に推移的でない。
クラスBに変更があった場合、クラスAは影響を受ける。
一方、クラスCやクラスDに変更があっても、クラスAは影響を受けない。
クラスCやクラスDに変更があったときに影響を受けるのはクラスBである。
endnote
@enduml