第3部:ドキュメントスキル / 第4章:ロジック実装

クラス図の読み方

クラス図は、システムの構造をクラス(データと処理のまとまり)の関係として表した図です。オブジェクト指向の設計で使われます。

📖 読了目安 約12分 対象:クラス構造、オブジェクト指向設計を理解する方

クラス図とは

役割

  • クラスの構造(属性とメソッド)を表現
  • クラス間の関係(継承、関連など)を表現
  • システムの全体構造を俯瞰

いつ使うか

設計理解時システム構造の把握
新機能実装時どのクラスに実装するか判断
コードリーディング時クラス間の関係を確認
リファクタリング時影響範囲の確認

クラス図の基本要素

クラスの表記

┌─────────────────────┐
│      User           │  ← クラス名
├─────────────────────┤
│ - id: int           │  ← 属性(フィールド)
│ - name: string      │
│ - email: string     │
├─────────────────────┤
│ + register()        │  ← メソッド
│ + login()           │
│ - validate()        │
└─────────────────────┘

可視性(アクセス修飾子)

記号意味説明
+publicどこからでもアクセス可能
-privateクラス内部からのみアクセス可能
#protected継承したクラスからアクセス可能
~package同じパッケージからアクセス可能

クラス間の関係とその読み方

クラスには6種類の関係があり、記法・意味が異なります。自分が読みたい関係のタブを開いてください。

クラス間に「つながり」がある関係です。

classDiagram
    User --> Order : 注文する
    class User {
        +id: int
        +name: string
    }
    class Order {
        +id: int
        +total: int
    }

読み方:「UserはOrderと関連がある(注文する)」

何が起きているか:ユーザーが注文を行うという「つながり」を示します。どちらが生存期間に影響するわけではありません。

「持っている」関係。部分は独立して存在できます。

classDiagram
    Team o-- Member : 所属
    class Team {
        +name: string
    }
    class Member {
        +name: string
    }

読み方:「TeamはMemberを持つ(Memberはチームがなくても存在できる)」

何が起きているか:メンバーはチームに所属していますが、チームが削除されてもメンバーは存在します。集約を示す◇の矢印に注目します。

「構成する」関係。部分は全体がないと存在できません。

classDiagram
    Order *-- OrderItem : 含む
    class Order {
        +id: int
    }
    class OrderItem {
        +productId: int
        +quantity: int
    }

読み方:「OrderはOrderItemで構成される(OrderがなければOrderItemも存在しない)」

何が起きているか:注文明細は注文があってこそ意味があります。注文が削除されると、その注文明細も自動的に削除されるべきです。コンポジションを示す◆の矢印に注目します。

「〜の一種である」関係。あるクラスが別のクラスを拡張します。

classDiagram
    Animal <|-- Dog
    Animal <|-- Cat
    class Animal {
        +name: string
        +eat()
    }
    class Dog {
        +bark()
    }
    class Cat {
        +meow()
    }

読み方:「DogはAnimalの一種である(Animalを継承している)」

何が起きているか:DogとCatはAnimalのすべての属性・メソッドを持ち、さらに自分固有のメソッドを追加しています。継承を示す△の矢印が子クラスから親クラスへ向きます。

インターフェースの実装関係。あるクラスがインターフェースの仕様を実装します。

classDiagram
    PaymentService <|.. CreditCardPayment
    PaymentService <|.. BankTransfer
    class PaymentService {
        <<interface>>
        +pay()
    }
    class CreditCardPayment {
        +pay()
    }
    class BankTransfer {
        +pay()
    }

読み方:「CreditCardPaymentはPaymentServiceインターフェースを実装している」

何が起きているか:複数の支払い方法(クレジットカード、銀行振込)が同じPaymentServiceインターフェースを実装することで、どの支払い方法でも同じ方法で呼び出せます。実装を示す破線の矢印に注目します。

一時的な「使う」関係。関連よりも一時的で弱い結びつきです。

classDiagram
    OrderService ..> EmailService : 使用
    class OrderService {
        +createOrder()
    }
    class EmailService {
        +send()
    }

読み方:「OrderServiceはEmailServiceを使う(依存している)」

何が起きているか:注文作成の際に、一時的にEmailServiceを使って通知メールを送ります。この関係は関連よりも一時的で、生存期間に影響しません。依存を示す破線の矢印に注目します。

関係の記号まとめ

関係線の種類矢印意味
関連実線つながりがある
集約実線◇→持っている(独立可)
コンポジション実線◆→構成している(一体)
継承実線△→〜の一種である
実装破線△→インターフェースを実装
依存破線一時的に使う

多重度(Multiplicity)

関係の「数」を表します。

表記意味
1ちょうど1つ
0..10または1つ
*0以上(複数可)
1..*1以上(複数可)
0..*0以上(複数可)(*と同じ)

classDiagram
    User "1" --> "*" Order : 注文する
    Order "1" --> "1..*" OrderItem : 含む

読み方

  • 「1人のUserは0個以上のOrderを持つ」
  • 「1つのOrderは1個以上のOrderItemを含む」

【サンプル】クラス図の実例

ECサイトの注文システムを例に、クラス図を読んでみましょう。

classDiagram
    User "1" --> "*" Order
    Order "1" *-- "1..*" OrderItem
    OrderItem "*" --> "1" Product
    Order --> PaymentService

    class User {
        -id: int
        -name: string
        -email: string
        +register()
        +login()
    }

    class Order {
        -id: int
        -userId: int
        -totalAmount: int
        -status: string
        +create()
        +cancel()
        +calculateTotal()
    }

    class OrderItem {
        -id: int
        -orderId: int
        -productId: int
        -quantity: int
        -price: int
    }

    class Product {
        -id: int
        -name: string
        -price: int
        -stock: int
        +checkStock()
    }

    class PaymentService {
        <<interface>>
        +pay()
        +refund()
    }

読み解き方

  1. User → Order:ユーザーは複数の注文を持つ(1対多)
  2. Order ◆ OrderItem:注文は注文明細で構成される(コンポジション)
  3. OrderItem → Product:注文明細は商品を参照する
  4. Order → PaymentService:注文は決済サービスを使う(依存)

実装時に確認すること

確認項目このクラス図から分かること
どのクラスを作るかUser, Order, OrderItem, Product, PaymentService
クラスの責務Orderにcreate, cancel, calculateTotalがある
データの関係OrderはOrderItemを複数持つ
外部連携PaymentServiceインターフェースで決済処理

クラス図を読むときのポイント

1. まず全体を俯瞰する

  • どんなクラスがあるか
  • 中心となるクラスは何か
  • クラスの数は多すぎないか

2. 関係の種類を確認する

  • 実線か破線か
  • 矢印の形は何か
  • 多重度はどうなっているか

3. 自分の担当範囲を特定する

  • 実装するのはどのクラスか
  • 関連するクラスは何か
  • 影響を受けるクラスはどこまでか

よくある疑問

継承と実装の違いは?
  • 継承:具体的なクラスを拡張(class Dog extends Animal)
  • 実装:インターフェースを実装(class CreditCard implements PaymentService)
集約とコンポジションの違いは?
  • 集約(◇):部分が独立して存在できる(チームとメンバー)
  • コンポジション(◆):部分は全体がないと存在できない(注文と注文明細)
クラス図に書いてないメソッドを追加していいか?

設計者に確認しましょう。ただし、privateなヘルパーメソッドなどは追加しても問題ないことが多いです。

関連ドキュメント