PlantUMLとクラス図（関連・依存・集約・合成）

関連とか依存をこんがらがることを見かけるので。

# クラス図

### 関連(Association)

:::note info
これはクラス間のより強い形の関連性を示します。あるクラスが他のクラスのオブジェクトを長期にわたって保持する場合、関連が存在します。関連はクラス図上で実線の矢印で表されます。
:::

Javaのクラス:

```java
public class Student {
    private String name;
    public Student(String name) {
        this.name = name;
    }
    // getter and setter methods...
}

public class Course {
    private String name;
    private List<Student> students;
    public Course(String name) {
        this.name = name;
        this.students = new ArrayList<>();
    }
    public void addStudent(Student student) {
        this.students.add(student);
    }
    // getter and setter methods...
}
```
対応するPlantUMLのクラス図:

```typescript
@startuml
class Student {
    - name : String
}

class Course {
    - name : String
    - students : List<Student>
    + addStudent(student : Student) : void
}

Student -- Course : includes >
@enduml
```

```plantuml
@startuml
class Student {
    - name : String
}

class Course {
    - name : String
    - students : List<Student>
    + addStudent(student : Student) : void
}

Student -- Course : includes >
@enduml
```

この例では、StudentクラスとCourseクラスの間に関連が存在します。CourseクラスはStudentクラスのオブジェクトのリストを保持しており、一つのCourseは複数のStudentを含むことができます。また、CourseクラスはStudentクラスに依存しています。なぜならaddStudentメソッドがStudentクラスのインスタンスを引数として取り、それをリストに追加しているからです。

### 依存関係(Dependency)

:::note info
これはクラス間の比較的弱い形の関連性を表します。あるクラスが他のクラスのメソッドを一時的に使用する場合や、あるクラスが特定のパラメータとして他のクラスを使用する場合に依存関係が存在します。依存関係はクラス図上で破線の矢印で表されます。
:::

Javaのクラス:

```java
public class Course {
    private String name;
    // constructor, getter and setter methods...
    public void printCourseDetails(Printer printer) {
        printer.print(name);
    }
}

public class Printer {
    public void print(String text) {
        System.out.println(text);
    }
}
```

対応するPlantUMLのクラス図:

```typescript
@startuml
class Course {
    - name : String
    + printCourseDetails(printer : Printer) : void
}

class Printer {
    + print(text : String) : void
}

Course ..> Printer : uses >
@enduml
```

```plantuml
@startuml
class Course {
    - name : String
    + printCourseDetails(printer : Printer) : void
}

class Printer {
    + print(text : String) : void
}

Course ..> Printer : uses >
@enduml
```

この例では、CourseクラスとPrinterクラスの間に依存関係が存在します。CourseクラスのprintCourseDetailsメソッドはPrinterクラスのインスタンスを一時的に利用しています。したがって、CourseクラスはPrinterクラスに依存しているといえます。この依存関係はPlantUMLクラス図上で破線の矢印で表示されます。

ただし、この依存関係はCourseクラスがPrinterクラスのインスタンスを長期にわたって保持しないため、関連ではありません。それらは一時的な関係であり、具体的にはCourseクラスがprintCourseDetailsメソッドを呼び出す際にのみ存在します。

### 集約（Aggregation）

:::note info
特殊な形式の関連（Association）を指します。集約は、あるクラスが他のクラスを保持し、それらが全体-部分の関係を持つことを示します。
:::

全体（親）オブジェクトが部分（子）オブジェクトのライフサイクルを管理するとはいえ、子オブジェクトが独立して存在できる場合にこの関係が存在します。つまり、親オブジェクトが破棄されても子オブジェクトは存続できます。

例えば、"School"と"Student"の関係を考えてみましょう。School（親）は多くのStudents（子）を持ちますが、SchoolがなくなってもStudentは存在し続けます。これは集約の一例です。

UMLクラス図では、集約関係は実線の矢印で表示され、矢印の親側には空のダイヤモンドが付きます。

PlantUMLを使って表現すると以下のようになります：

```
@startuml
class School {
}

class Student {
}

School "1" o-- "*" Student : contains
@enduml
```

```plantuml
@startuml
class School {
}

class Student {
}

School "1" o-- "*" Student : contains
@enduml
```

ここで、o-- は集約を示し、"1"と"*"はそれぞれ全体と部分の多重度を表現しています（1つの学校が多数の学生を持つ）。

### 合成（Composition）

:::note info
合成は集約よりも強い関連性を持ち、それは全体-部分の関係を表す特別な形式の関連（Association）です。
:::

合成の場合、部分（子）オブジェクトは全体（親）オブジェクトに完全に依存しており、親オブジェクトがなくなると子オブジェクトも破棄されます。これは子オブジェクトが親オブジェクトなしには存在できないという意味です。

例えば、「Person」と「Heart」の関係を考えてみましょう。Person（親）はHeart（子）を持ちますが、PersonがなくなるとHeartも存在できません。これは合成の一例です。

UMLクラス図では、合成関係は実線の矢印で表示され、矢印の親側には黒塗りのダイヤモンドが付きます。

PlantUMLを使って表現すると以下のようになります：

```
@startuml
class Person {
}

class Heart {
}

Person "1" *-- "1" Heart : has
@enduml
```

```plantuml
@startuml
class Person {
}

class Heart {
}

Person "1" *-- "1" Heart : has
@enduml
```

ここで、*-- は合成を示し、"1"と"1"はそれぞれ全体と部分の多重度を表現しています（1人の人間が1つの心臓を持つ）。

# privateメソッドは書くのか？

クラス図にどの程度の詳細を含めるかは、その図が何を表現することを意図しているかによります。

一般的に、UMLクラス図はクラスの公開インターフェースを示すものであり、それは外部から見える振る舞いと属性を示すことを意図しています。したがって、多くのクラス図ではpublicメソッドと属性のみが表示されます。

しかし、クラスの内部動作をより詳細に理解するために、または設計の観点からクラス図を使用する場合、privateメソッドや属性も含めることがあります。これは設計プロセスやデバッグに役立つことがあります。

したがって、クラス図にprivateメソッドを記載するかどうかは、 ***その図の目的や視聴者による*** ところが大きいです。ただし、全てを記載すると図が複雑になりすぎて読みにくくなる可能性があるため、適切なバランスを見つけることが重要です。

# そもそもの記載方法

めっちゃ参考になります！

https://qiita.com/ykawakami/items/f6688b845945669f0ce5