もう辛くない！テキストで書くUML クラス図編


# はじめに

PlantUMLを使用し、クラス図を描く方法をまとめます。

※PlantUMLを使える環境が整っている前提で進めます。

# 定義

## クラス

`class クラス名` とすることでクラスを定義することができます。

```
@startuml

class A

@enduml 
```

![class_1.png](https://qiita-image-store.s3.amazonaws.com/0/85396/ba77fe68-3aff-6334-c7ad-44135b09cda1.png)

クラスにフィールドやメソッドを定義する場合は、以下のように定義します。

```
@startuml

class A {
  id: number
  fun()
}

@enduml 
```

![class_2.png](https://qiita-image-store.s3.amazonaws.com/0/85396/98cc828d-c6d8-ccba-dda8-51b646be525a.png)


フィールドやメソッドに `{static}` 、 `{abstract}` を付けることで、
staticなフィールドや抽象メソッドなどを定義することもできます。

```
@startuml

class A {
  {static}id: number
  {abstract}func1()
  {static}func2()
}

@enduml 
```

![class_3.png](https://qiita-image-store.s3.amazonaws.com/0/85396/8ce56741-0255-a29e-de2f-5f6ac2ec2a8d.png)


## インターフェース

`interface インターフェース名` とすることでインターフェースを定義することができます。

```
@startuml

interface A 

interface B {
  id: number
  name: string
}

@enduml 
```

![interface.png](https://qiita-image-store.s3.amazonaws.com/0/85396/48196e93-eaf8-56f4-8405-cbe4d7350ac0.png)

## 抽象クラス

`abstract クラス名` または `abstract class クラス名` とすることで、
抽象クラスを定義することができます。

```
@startuml

abstract A

abstract class B

abstract C {
  id: number
  name: string
}

@enduml
```

![abstract_class.png](https://qiita-image-store.s3.amazonaws.com/0/85396/46cd71fd-a971-d5ec-b69e-de6e1facf472.png)

## 列挙型

`enum 列挙型名` とすることで、列挙型を定義することができます。

```
@startuml

enum A {
  type1
  type2
}

@enduml
```

![enum.png](https://qiita-image-store.s3.amazonaws.com/0/85396/012d1125-1fc7-cec6-58bf-82dccc5b5eca.png)

## アクセス修飾子

フィールド名やメソッド名の前に記号を付けることで、可視性を定義することができます。

| 記号 | アクセス修飾子 |
|:--|:--|
| + | public |
| - | private |
| # | protected |
| ~ | package |

```
@startuml

class A {
  +id: number
  -name: string
  #func1()
  ~func2()
}

@enduml
```

![access.png](https://qiita-image-store.s3.amazonaws.com/0/85396/be22a38a-f77b-9d94-7c09-354c88b8e22c.png)

# クラス同士の関連

クラス同士を記号でつなぐことで、関連を定義することができます。
`-` (ハイフン)で繋ぐ場合は実線、 `.` (ドット)で繋ぐ場合は波線を表し
線を表す記号の左右に記号を付けることで矢印などの向きを変えることができます。


`-` や `.` の数によって、図の配置や線の長さを変えることができます。

| 線を表す記号の数 | 表示 |
|:--|:--|
| 1文字 | 図を横に並べて関連付けされる |
| 2文字 | 図を縦に並べて関連付けされる |
| 3文字以上 | 図を縦に並べて関連付けされる<br/>線の長さが長くなる |

```
@startuml

A - B
C -- D
E --- F
G ---- H

@enduml
```

※上記のように、定義がされていないものを関連付けした場合はクラスとして扱われます。


![relation_2.png](https://qiita-image-store.s3.amazonaws.com/0/85396/aa830744-6afd-2984-77b3-c52d0b3dd014.png)

また、`-left-` のように線を表す記号の間に位置を指定することで
図を配置する方向を指定することができます。

```
@startuml

A -right- Right
A -left- Left
A -up- Up
A -down- Down

@enduml
```

![location.png](https://qiita-image-store.s3.amazonaws.com/0/85396/a766d797-0cfc-2427-b78b-010bef127d8c.png)



## 関連

`-` または `<-` を使用することで関連を定義することができます。

`<-` はシーケンス図のメッセージを表す記号なため、
クラス定義を事前に行ってない場合はシーケンス図として認識されてしまします。

```
@startuml

A - B
B --> C
A <-- C

@enduml
```
![association.png](https://qiita-image-store.s3.amazonaws.com/0/85396/9905a693-912d-be73-b806-cb493d46c62c.png)


## 集約

`o-` を使用することで、集約を定義することができます。

```
@startuml

A o- B

@enduml
```

![aggregation.png](https://qiita-image-store.s3.amazonaws.com/0/85396/f97ec27c-0898-9a21-de6a-fc664722fb48.png)


## コンポジション

`*-` を使用することで、コンポジションを定義することができます。

```
@startuml

A *- B

@enduml
```

![composition.png](https://qiita-image-store.s3.amazonaws.com/0/85396/1b4b457a-401e-c67d-ce9a-023400130989.png)

## 依存

`<.` を使用することで、依存を定義することができます。

```
@startuml

A <. B

@enduml
```

![dependency.png](https://qiita-image-store.s3.amazonaws.com/0/85396/6f3e736e-5c42-b22e-bf08-b53643ed6591.png)


## 汎化

`<|-` を使用することで、汎化を定義することができます。

```
@startuml

A <|-- B

@enduml
```

![generalization.png](https://qiita-image-store.s3.amazonaws.com/0/85396/970fd927-ff65-7112-e8d3-539f68b46106.png)


## 実現

`<|.` を使用することで、実現を定義することができます。

```
@startuml

interface A
class B

A <|.. B

@enduml
```

![realization.png](https://qiita-image-store.s3.amazonaws.com/0/85396/1e702608-1cfd-ffcd-293d-af2d965d6b75.png)


## ロリポップ

`()-` を使用することで、ロリポップで実現を表現することも可能です。

```
@startuml

A -() Interface

@enduml
```

![lolippop_1.png](https://qiita-image-store.s3.amazonaws.com/0/85396/f9e2bec3-85f2-a12f-268c-08f65e82b67b.png)


## 多重度

クラス名と関連を表す記号の間に `"` で囲んで多重度を指定することができます。
多重度は日本語でも問題ありません。 

```
@startuml

A "1" *-- "0..*" B

@enduml
```

![multiplicity.png](https://qiita-image-store.s3.amazonaws.com/0/85396/62db9ed3-7f70-0784-b1f3-7006a9f40497.png)


## ラベルを付ける

関連の後ろに `:` で区切ってラベルを指定することができます。
`>` や `<` をラベルに使用すると、関係を示す方向を表現することもできます。

```
@startuml

A - B : A-Bラベル
B -- C : B-Cラベル >

@enduml
```

![label.png](https://qiita-image-store.s3.amazonaws.com/0/85396/03918144-c3f3-ce53-b260-20026b7021d0.png)

# Package

`package パッケージ名 {}` とすることで、パッケージを定義することができます。
`{}` の中にクラス定義や関連を定義することができ、packageを入れ子にすることも可能です。

```
@startuml

package package1 {
  class A
  package sub {
  }
}

package package2 {
  class B
  A <|-- B
}

@enduml
```

![package.png](https://qiita-image-store.s3.amazonaws.com/0/85396/3ffedd1a-e907-be9e-8eac-3f5a027e49a2.png)

# ノート

図にはノートを付けることができます。
ノートは上下左右どの位置に表示するかを指定することができます。

| ワード | 表示位置 |
|:--|:--|
| top | 上 |
| bottom | 下 |
| left | 左 |
| right | 右 |

一行のコメントを書く場合は `note 表示位置: コメント` 、
複数行のコメントを書く場合は `note 表示位置` 、 `end note` の間にコメントを記述します。

```
# 一行の場合
note left: コメント

# 複数行の場合
note left
  コメント
  …
end note
```

## クラスにノートを付ける

`note 表示位置 of クラス名` とすることで、指定したクラスにノートを付けることができます。
また、 ノートを付けるクラスとノートの定義が離れていない場合は、
クラス名を指定せずにノートを付けることができます。

```
@startuml

class A
class B

note left: クラスBのコメント
note right of A
  クラスAのコメント
  …
end note

@enduml
```

![class_note.png](https://qiita-image-store.s3.amazonaws.com/0/85396/e7d367e1-a17a-3864-a328-8b1abfb72c48.png)

### ノートを複数のクラスに紐付ける

`note as ノート名` としてノートを定義しておき、
後から、複数のクラスにノートを紐付けることも可能です。

```
@startuml

class A
class B

note as N
  複数のクラスに紐付ける
end note

N .. A
N .. B

@enduml
```

![association_note.png](https://qiita-image-store.s3.amazonaws.com/0/85396/1b76cfbe-9032-7070-14d3-fef0d924b414.png)


### フィールドやメソッドにノートを付ける

ノートを付けるフィールドやメソッド名は `クラス名::フィールド名` または `クラス名::メソッド名` のように、
クラス名の後ろに `::` を付けることで指定します。

※1行の記法で指定するとうまくいかないため、複数行の記法で記述しています。

```
@startuml

class A {
  id: number
  func()
}

note right of A::id
  idのコメント
end note
note right of A::func
  func()のコメント
end note

@enduml
```

![feild_method_note.png](https://qiita-image-store.s3.amazonaws.com/0/85396/d57b6689-cb67-6591-b715-f60927edb74f.png)

アクセス修飾子がついている場合も、
フィールド名やメソッド名を指定することでノートを付けることができます。

```
@startuml

class A {
  +id: number
  -func()
}

note right of A::id
  idのコメント
end note
note right of A::func
  func()のコメント
end note

@enduml
```

![feild_method_note_2.png](https://qiita-image-store.s3.amazonaws.com/0/85396/21161e07-c0cf-4483-69c9-90b5a065dad4.png)

## 関連にノートを付ける

`note 表示位置 on link` とすることで、
関連に対してコメントをつけることができます。

```
@startuml

A .> B
note right on link
  A-Bに対するコメント
end note
B o-- C
note left on link
  B-Cに対するコメント
end note

@enduml
```

![associate_link_note.png](https://qiita-image-store.s3.amazonaws.com/0/85396/552b0b82-64bb-58a9-d703-7baedfb5f816.png)

# 色やフォントを変更

カラーコードを指定することで、クラスやノートなどの色を変更できます。

```
@startuml

class A #F5A9BC

note as N #A9C6F6
  コメント
end note

package package1 #CEF6F5 {
  package package2 #F7F8E0 {
  }
}

@enduml
```

![color.png](https://qiita-image-store.s3.amazonaws.com/0/85396/f346d84c-8b95-3916-76e6-503dda352251.png)

## skinparamコマンド

`skinparam` コマンドを使用することで、色やフォントをまとめて変更することもできます。

使用できるパラメータは、下記のURLから確認できます。
[PlantUML skinparam](http://plantuml.com/skinparam)

```
@startuml

skinparam class {
  BackgroundColor #FFFFFF
  BorderColor Black
  ArrowColor Red
  FontName Impact
}


interface A
abstract class B
class C
class D

A <|.. C
B <|-- D
C - D

@enduml
```

![skinparam.png](https://qiita-image-store.s3.amazonaws.com/0/85396/ce60248f-092a-22bb-1557-a447c83a9f7d.png)


# 参考サイト

[PlantUML](http://plantuml.com/)