「詳細設計でシーケンス図も作ってください」と言われたものの、どこまで描けばよいのか迷ったことはありませんか。
シーケンス図は、処理に登場するライフライン同士のやり取りを、時間の流れに沿って表す図です。詳細設計では、呼び出し順・責務・分岐・例外処理などを、実装前にレビューできる形へ落とすために使えます。
ただし、「詳細設計なら必ずシーケンス図を作る」という共通ルールがあるわけではありません。成果物の種類や粒度はプロジェクトごとに異なるため、まずは現場の設計標準を確認するのが前提です。
シーケンス図とは「誰が・誰を・どの順番で呼ぶか」を表す図
シーケンス図はUML(Unified Modeling Language)で定義される相互作用の表現の一つです。縦方向に時間が進み、参加者の間をメッセージが行き来することで、処理の順番を追えるようにします。
詳細設計で見るときは、記号を暗記するより「この図を見た実装者が処理の流れを説明できるか」を意識すると理解しやすくなります。
| 要素 | 意味 | 詳細設計で見るポイント |
|---|---|---|
| 参加者 / ライフライン | 処理に登場する利用者・クラス・サービス・DBなど | 責務の分け方が妥当か |
| メッセージ | 参加者間の呼び出しや応答 | 呼び出し先と順番が合っているか |
| 実行区間 | 処理を実行している期間の表現 | どこが処理主体か読み取れるか |
| alt / opt | 条件分岐・任意処理 | 正常系と例外系を分けられているか |
| loop | 繰り返し | 繰り返し条件が曖昧でないか |
| Note | 補足説明 | 図だけでは伝わらない制約を補えているか |
MermaidやPlantUMLでも、参加者・メッセージ・分岐・繰り返しといった考え方をテキストで表現できます。ツールごとに記法は異なるため、実務ではプロジェクトで採用している書式を優先しましょう。
詳細設計でシーケンス図を書く3つの目的
1. 基本設計の外部仕様を内部処理へつなぐ
基本設計で「ユーザー登録APIはこの入力を受け、この結果を返す」と決めても、内部でどのクラスが何を担当するかまでは決まっていないことがあります。
シーケンス図にすると、Controller → Service → Repositoryのように、外部仕様を内部の責務へ分解できます。実装者が「この判定はどこで行う?」と毎回決め直す状態を減らせます。
2. 分岐・例外・外部連携の抜けを見つける
正常系だけを文章で追っていると、重複データ、認証失敗、外部APIエラーなどの扱いが後回しになりがちです。
シーケンス図では、条件分岐をalt、任意処理をopt、繰り返しをloopのような枠で表現できます。処理の分かれ目が視覚化されるため、「この失敗時は誰が何を返すのか」をレビューしやすくなります。
3. 実装・テストの共通認識を作る
設計者はServiceで例外化するつもりでも、実装者はControllerで判定すると考えている。こうした認識差は、コードを書き始めてから気づくと手戻りになります。
シーケンス図で責務と順序を見せておけば、レビュー時に差分を見つけやすくなります。さらに正常系・分岐・失敗経路は、結合テストの観点を洗い出す材料にもなります。
ユーザー登録APIの例で流れを見る
たとえば「メールアドレスが未登録ならユーザーを作成し、重複していれば409を返す」という例を考えます。これは説明用のサンプルであり、特定システムの仕様ではありません。
@startuml
actor User
participant UserController as Controller
participant UserService as Service
database UserRepository as Repository
User -> Controller: POST /users
Controller -> Service: create(command)
Service -> Repository: findByEmail(email)
Repository --> Service: existingUser?
alt メールアドレスが登録済み
Service --> Controller: DuplicateEmailException
Controller --> User: 409 Conflict
else 未登録
Service -> Repository: save(user)
Repository --> Service: savedUser
Service --> Controller: result
Controller --> User: 201 Created
end
@enduml
この図で確認したいのは矢印の見た目ではありません。主に次の4点です。
- 外部リクエストを受ける責務がControllerにある
- 業務判断をServiceへ寄せている
- データ参照・保存をRepositoryへ分けている
- 重複時と未登録時の処理が分岐として明示されている
実際の案件では、認証、入力検証、トランザクション、イベント送信なども設計対象になることがあります。必要なものだけを追加し、図が実装コードの逐語訳にならないようにします。
シーケンス図の書き方を5手順で整理する
1. まず1つのシナリオを決める
最初に「ユーザー登録」「注文確定」「ログイン失敗」のように、何の処理を描くかを決めます。
一枚で機能全体を表そうとすると分岐が増え、誰も追えない図になりやすくなります。基本設計のユースケースやAPI単位を起点にすると切り出しやすいでしょう。
2. 参加者を「責務」で並べる
次に、処理に必要な参加者を挙げます。Webアプリなら、利用者、Controller、Service、Repository、DB、外部APIなどが候補です。
ここでクラスを細かく並べすぎると、設計意図より実装詳細が目立ちます。「この処理の責務を理解するために必要か」で残す参加者を決めます。
3. 正常系を上から順番に置く
参加者が決まったら、正常に完了する経路を先に追います。誰が呼び出し、誰が応答し、次にどこへ進むかを並べます。
メッセージ名は「処理」「確認」のような曖昧語より、findByEmail、saveのように意図が分かる表現にするとレビューしやすくなります。
4. alt・opt・loopで分岐を足す
正常系が通ったら、失敗や条件分岐を追加します。すべてを一枚へ詰める必要はありませんが、仕様上重要な分岐が図から消えていないかは確認します。
- alt:条件によって経路が分かれる
- opt:条件を満たす場合だけ実行する
- loop:同じやり取りを繰り返す
MermaidとPlantUMLはいずれも、これらに相当するグループ化記法を提供しています。
5. 設計書・コード・テスト観点と照合する
最後に、シーケンス図だけを見て完成としません。API仕様、クラス設計、DB設計、例外方針などと矛盾がないかを確認します。
設計後に実装方式が変わった場合も、図を残すなら更新対象です。古いシーケンス図が残ると、次の改修で誤った前提として読まれてしまいます。
ダメな例は「処理」が多くて責務が見えない
シーケンス図を書いたのに設計レビューで会話が進まない場合、メッセージが抽象的すぎることがあります。
ダメな例
Controller -> Service: 処理する
Service -> DB: 確認する
Service -> DB: 登録する
Service --> Controller: 結果
これでは「何を確認するのか」「どこで重複判定するのか」「失敗時にどうなるのか」が読み取れません。
修正例
Controller -> Service: createUser(command)
Service -> Repository: findByEmail(email)
Repository --> Service: existingUser?
alt 重複あり
Service --> Controller: DuplicateEmailException
else 重複なし
Service -> Repository: save(user)
end
修正例では、呼び出しの意図と分岐条件が追えます。詳細設計では「矢印を増やす」より、実装時に必要な判断を図へ残すことが重要です。
よくある5つの落とし穴
1. getterやログ出力まで全部描く
細かさは正確さと同じではありません。レビュー対象の責務・分岐・外部境界に関係しない処理まで描くと、重要な流れが埋もれます。
2. 抽象度の違う参加者を混ぜる
「注文システム」という大きな箱と、特定のprivateメソッドを同じ粒度で並べると読みづらくなります。論理設計なのか、クラスレベルの詳細設計なのかを揃えます。
3. 正常系しか描かない
実装で迷いやすいのは、失敗したときです。認証失敗、データなし、重複、外部連携失敗など、仕様上重要な経路は設計段階で確認します。
4. 図とインターフェース名がずれる
シーケンス図ではregister()、クラス設計ではcreateUser()のように名前がずれると、どちらが正しいのか分からなくなります。設計書間で用語と責務をそろえましょう。
5. 「UML的に正しい」ことが目的になる
UMLの記法を正しく使うことは大切ですが、詳細設計の目的は記号テストに合格することではありません。実装者とレビュアーが同じ処理を想像できる粒度になっているかを優先します。
PlantUMLとMermaidはどちらを使う?
どちらもテキストからシーケンス図を生成できるため、Gitで設計ソースを管理したい現場では扱いやすい選択肢です。
PlantUMLは参加者とメッセージをテキストで定義し、alt、opt、loop、parなどのグループ化も扱えます。Mermaidも参加者、メッセージ、activation、loop、alt、opt、parなどを記述できます。
ただし、ツール選定より先に確認したいのは「そのリポジトリやドキュメント基盤で何が標準か」です。既存の図がPlantUMLならPlantUMLへ合わせる。Markdown中心でMermaidが標準ならMermaidを使う。設計資産を同じ方法で更新できることを優先しましょう。
どこまで描けば詳細設計として十分?
迷ったら、「実装時の重要な判断が図から読み取れるか」で線を引きます。
- 主な参加者と責務が分かる
- 重要な呼び出し順が分かる
- 正常系と主要な分岐・例外が分かる
- 外部APIやDBなどの境界が分かる
- 非同期処理やトランザクションが重要なら、その扱いを設計資料として追える
- 基本設計やクラス設計と用語が一致している
逆に、ローカル変数の代入や自明なgetter呼び出しまで追わないと実装できないケースでなければ、そこまで図へ入れる必要はありません。
また、シーケンス図が必須成果物かどうかはプロジェクトのテーラリングや設計標準によります。IPAの共通フレームも、ライフサイクルの作業や役割を共通の枠組みとして扱いつつ、工程へのマッピング例を唯一の推奨体系とはしていません。現場の成果物定義を先に確認しましょう。
レビュー前に確認したい7項目
- 対象シナリオがタイトルや前提から分かるか
- 参加者の責務と粒度がそろっているか
- メッセージ名が具体的で、設計書間の用語と一致しているか
- 正常系だけでなく主要な分岐・例外が入っているか
- 外部システム・DB・非同期処理など境界が見えるか
- 基本設計の入出力や業務ルールと矛盾していないか
- 図の情報量が多すぎず、実装者が処理順を追えるか
この7つを確認できれば、シーケンス図は「きれいな図」ではなく、実装とレビューをつなぐ設計資料として機能しやすくなります。
まず1つのAPIを正常系+例外系で描いてみる
詳細設計のシーケンス図は、処理に登場する参加者とメッセージを時間順に並べ、内部の責務と分岐を共有するための図です。
最初から大規模な機能を描く必要はありません。まず手元のAPIを一つ選び、Controller・Service・Repository・外部境界を並べて、正常系と主要な例外系を一本ずつ追ってみてください。
その図を見ながら「この判断は誰の責務か」「失敗時はどこへ戻るか」を説明できれば、詳細設計として次の実装へつながる形になっています。