クラス図とは?UMLの書き方・関連や多重度・集約とコンポジションの違いを解説
クラス図とは、システムがどんなクラスで組み立てられ、それらがどうつながっているかを一枚で表すUMLの図です。処理の順序ではなく、システムの「静的な骨格」を描く点に特徴があります。この記事では、クラスを表す3段ボックスと可視性の記法から、関連・多重度・集約・コンポジション・汎化・依存という関係の使い分け、実務でつまずきやすい集約とコンポジションの切り分け方、オブジェクト指向設計との対応、MermaidやPlantUMLでコードとして管理する方法、そして詳細設計で書くべき場面と過剰設計になる失敗パターンまでを、設計と実装の現場視点で整理します。
目次
まとめ:クラス図の構成要素・関係の書き方と設計での役割
クラス図の芯は、システムを構成する部品(クラス)と、その部品同士のつながりを静的に描くことにあります。各クラスは、クラス名・属性・操作を上から並べた3段のボックスで表し、線と記号で他のクラスとの関係を結びます。時間軸に沿った動きは描きません。それはシーケンス図の担当です。
関係の種類は6つ押さえれば実務は回ります。単純なつながりを表す関連、数の対応を示す多重度、全体と部分を表す集約とコンポジション、継承を表す汎化、一時的な利用を表す依存です。もっとも取り違えやすいのが集約とコンポジションで、本記事では「部分のライフサイクルが全体に縛られるか」で切り分ける判断基準を示します。
クラス図が効くのは、詳細設計とオブジェクト指向設計の工程です。クラスの責務と関係を先に固めておくと、実装のぶれと後戻りを抑えられます。反面、すべてのクラスを漏れなく描こうとすれば、保守されない紙の設計図に終わりがちです。どこまで描き、どこで手を止めるか、その線引きまで条件付きで言い切ります。
クラス図とは何か:UMLにおける定義とクラスを表す3段ボックスの書き方
はじめに言葉の範囲をそろえます。クラス図は、システムの構造を「どんなクラスがあり、互いにどうつながるか」で捉える図です。プログラムが動く順番ではなく、部品の設計図として読む点が、他のUML図と分かれる出発点になります。
クラス図の定義と、静的な構造を表すUMLの構造図としての位置づけ
クラス図は、UML(Unified Modeling Language)で定義された構造図の一種で、システムを構成するクラスと、その属性・操作・相互関係を表します。狙いは、実装に入る前に「システムがどんな部品でできているか」を設計として固めることです。たとえばECサイトなら、User(利用者)、Order(注文)、Product(商品)といったクラスを箱で並べ、注文が商品を複数持つ、といった関係を線で結びます。処理の流れを追うシーケンス図が「時間軸の動き」を表すのに対し、クラス図が描くのは時間の概念を持たない「静的な構造」です。この違いが、両者を使い分ける土台になります。
クラスを表す3段ボックス(クラス名・属性・操作)の記法と書き方
クラス図の主役であるクラスは、上下3段に区切った長方形で表します。記法は単純で、段の意味さえ押さえれば読み書きに迷いません。
- 上段:クラス名。中央寄せで、頭文字を大文字にした名詞で書く(
Orderなど) - 中段:属性。そのクラスが持つデータ項目を「属性名: 型」の形で並べる(
total: intなど) - 下段:操作。そのクラスが提供するメソッドを「操作名(引数): 戻り値の型」で並べる
属性はクラスが保持する状態、操作はクラスが振る舞える動作にあたります。抽象クラスやインターフェースを表す場合は、クラス名を斜体にしたり <<interface>> というステレオタイプを添えたりして区別します。設計の初期は属性と操作をすべて書き切らず、名前と主要な項目だけで骨格を描き、詳細化とともに埋めていくのが実務の進め方です。
属性と操作に付ける可視性(公開・非公開・限定公開)の記号と書き方
属性や操作の先頭には、外部からのアクセス範囲を示す可視性の記号を付けます。オブジェクト指向のカプセル化を図の上で表現する部分で、記号の意味は4つです。+ は公開(public・どこからでもアクセス可)、- は非公開(private・自クラス内のみ)、# は限定公開(protected・自クラスと継承先)、~ はパッケージ内公開を指します。たとえば - password: string は、パスワードを外部から直接触らせない設計意図の表れです。可視性を図に書き込めば、どの属性を隠し、どの操作を窓口として公開するかという設計判断が一目で伝わります。カプセル化・継承・ポリモーフィズムといった、クラス図が前提とする考え方はオブジェクト指向のカプセル化・継承・ポリモーフィズムで整理しています。
クラス図の関係の種類:関連・多重度・集約・コンポジション・汎化・依存の使い分け
クラス図で表現に差が出るのは、線と記号の引き方です。関係を正しく使い分けられると、図がシステムの構造を語り始めます。逆に取り違えると、設計意図が読み手に伝わらない図になります。
関連(association)と多重度で「いくつと結びつくか」を表す書き方
関連は、クラス同士がつながっていることを示す最も基本の線で、単純な実線で引きます。User と Order を線で結べば、利用者が注文と関係を持つという構造の表現です。この線の両端に付ける数字が多重度で、片方のクラスから見てもう片方がいくつ対応するかを示します。表記は 1(ちょうど1つ)、0..1(0または1)、1..*(1つ以上)、*(0以上)のように書きます。たとえば「1人の利用者は0件以上の注文を持つ」なら、User側に 1、Order側に 0..* と添える書き方です。多重度を明示すれば、必須か任意か、単数か複数かというデータ構造の制約がそのまま図に残り、後工程のテーブル設計や実装の判断根拠になります。
集約(has-a)とコンポジションでライフサイクルの強さを描き分ける
集約とコンポジションは、どちらも「全体と部分」の関係を表しますが、結びつきの強さが違います。集約(aggregation)は、白抜きのひし形を全体側に付けて表す、ゆるい has-a 関係です。部分は全体から独立して存在できます。たとえば「部署」と「社員」は、部署が解散しても社員は別の部署へ移れるため集約が向きます。コンポジション(composition)は、塗りつぶしのひし形で表す、強い全体と部分の関係です。全体が消えると部分も消えます。「注文」と「注文明細」なら、注文が削除されれば明細も存在意義を失うため、コンポジションでの表現が自然です。ひし形の色(白抜きか塗りつぶしか)が、部分の生存が全体に縛られるかどうかを示すしるしになります。
汎化(is-a)・実現・依存でクラスの継承と利用の関係を表す書き方
残る3つの関係は、継承や一時的な利用を表すものです。汎化(generalization)は、is-a のクラス継承を示す関係で、中実の三角矢印で親クラスを指します。「正社員」「アルバイト」を「従業員」から汎化で派生させれば、共通の属性を親に持たせ、差分だけを子に描けます。実現(realization)は、インターフェースとその実装クラスの関係を破線の三角矢印で表す記法です。依存(dependency)は、あるクラスが別のクラスを引数や戻り値で一時的に使うだけの弱い関係で、破線の矢印で示します。汎化と実現が「構造として持ち続ける関係」なのに対し、依存は「その場限りで参照する関係」という濃淡を、矢印の実線・破線で描き分けます。
集約とコンポジションを取り違えないための設計上の判断基準と考え方
設計者がもっとも迷うのが、集約とコンポジションの区別です。見た目のひし形が似ているため、意味を意識しないと混同しがちです。「部分が全体なしに存在できるか」の1軸で切り分けると、迷いが消えます。次の表で対比します。
| 観点 | 集約(aggregation) | コンポジション(composition) |
|---|---|---|
| ひし形の記号 | 白抜き(全体側に付ける) | 塗りつぶし(全体側に付ける) |
| 結びつきの強さ | ゆるい(部分は独立して存在) | 強い(部分は全体に従属) |
| 全体が消えたときの部分 | 残る(別の全体へ移せる) | 一緒に消える |
| 例 | 部署 と 社員 | 注文 と 注文明細 |
迷ったら「全体を削除したとき、その部分は単独で意味を持つか」を自問します。意味を持つなら集約、意味を失うならコンポジションです。実務では、この2つを厳密に描き分けるより、まず関連と多重度だけで構造を固め、生存が明らかに従属する箇所にだけコンポジションを足すのが読みやすさを保つ書き方になります。ひし形の描き分けにこだわりすぎて設計が進まないなら、いったん関連で描いて先へ進む判断も現場では要ります。
クラス図の書き方:オブジェクト指向の設計からコード管理までの手順
要素と関係を押さえたら、実際に描く手順に移ります。いきなり細部の属性から書き始めず、クラスの洗い出しと責務の割り当てから固めるのが、破綻しない図への近道です。ここでは作成の流れと、オブジェクト指向設計との対応、コードで管理する方法までを扱います。
クラスと属性・操作を洗い出す手順とオブジェクト指向設計との対応
クラス図は、次の4ステップで組み立てると過不足がありません。上流の概念から順に確定させます。
- クラスを洗い出す:システムに登場する「もの」や「概念」を名詞で挙げる(利用者・注文・商品など)
- 責務を割り当てる:各クラスが持つべきデータ(属性)と振る舞い(操作)を決める
- 関係を結ぶ:クラス間を関連・多重度でつなぎ、全体と部分や継承を集約・コンポジション・汎化で足す
- 可視性を調整する:外部に見せる操作と、内部に隠す属性を可視性記号で仕分ける
この手順は、オブジェクト指向設計の考え方と重なります。クラスを1つの責務にまとめる作業は、属性と操作を1箇所に閉じ込めるカプセル化そのものです。共通する性質を親クラスへ引き上げる作業は継承にあたり、同じ操作名で異なる振る舞いを持たせる設計はポリモーフィズムへつながります。クラス図を描くこと自体が、オブジェクト指向でシステムを分割する訓練になるわけです。個々の設計概念の意味はオブジェクト指向とは何かで扱っているので、あわせて読むと図の背景が腑に落ちます。
MermaidやPlantUMLでクラス図をコードとして管理する方法
作図ツールで描いたクラス図は、クラスの追加や属性変更のたびに手で描き直す手間がかかります。バージョン管理と相性がよいのが、テキストから図を生成するツールです。PlantUMLは class Order { +total: int } のような記法でクラスを書き、集約やコンポジションも記号で表現しながら、Gitでdiffを取って管理できます。より軽量な選択肢がMermaidで、Markdown内に classDiagram のブロックを書けば、GitHubやドキュメントツールでそのまま描画される手軽さがあります。図をコードで持てば、レビューで差分を追え、設計と実装のずれを早く検知できるのが利点です。GSCで「クラス図 mermaid」という実クエリが確認できるとおり、コードで図を描く需要は現場で根強くあります。Mermaidの具体的な記法とエディタでの試し方はMermaid記法の使い方にまとめました。ツールに任せる前に、関係の記号の意味を理解しておくと、生成された図の善し悪しを判断できます。
詳細設計の工程でクラス図を使う判断と、書くべきでない場面の見極め
ここからは立場を明確にします。クラス図は、どんな開発でも必ず描くべき図ではありません。効く工程と規模があり、逆に描くことが手間だけを増やす状況もあります。どちらかを見極める基準を、具体的な条件で示します。
詳細設計・オブジェクト指向設計でクラス図が効く場面と成果物としての扱い
クラス図がもっとも力を発揮するのは、外部設計から内部設計・詳細設計へ進む段階です。画面や機能をどんなクラスへ分解し、どのクラスがどの責務を持つかを、実装前に関係者で合意できます。とくに複数人で開発する場合、クラスの責務と関係を図で共有しておけば、担当ごとの実装のぶれを抑えられるのが利点です。工程全体のどこにクラス図という設計成果物が位置づくかはシステム開発の工程と7フェーズの成果物の全体像が判断の土台で、その中の設計フェーズの詳細は外部設計と内部設計の違い・成果物で扱っています。同じUMLでも、システムの機能範囲を利用者目線で洗い出す段階はユースケース図が担い、その内部構造をクラス図で詳細化する、という順に使い分けます。本記事は、その設計工程で使うモデリング手法そのものを掘り下げる役割です。
クラス図を書かない方がよい場面と、過剰設計になりがちな失敗パターン
クラス図を描くべきでない場面もはっきりあります。第一に、ごく小規模なスクリプトや、クラス構造が自明な使い捨てのツールです。数個のクラスなら、図を描くより先にコードを書いたほうが速く、正確に伝わります。第二に、手続き型で書かれ、そもそもクラス分割が薄いシステムです。無理にクラス図へ当てはめても、構造を表しきれません。ありがちな失敗は3つあります。すべてのクラスと属性を漏れなく描こうとして、実装と乖離した巨大な図を保守できなくなること。ゲッターやセッターまで操作欄に書き込み、本質的な設計判断が埋もれること。そして図を作ること自体が目的化し、コードが変わっても更新されないまま放置されることです。三つに共通するのは、クラス図が合意と設計判断の道具であるという原点を見失っている点にあります。全体像を1枚に描き切ろうとせず、設計判断が要る中核のクラス群に絞るほうが、図は長く使われます。
受託開発で保守しやすいクラス設計を業務要件から作る体制の作り方
クラス図が真価を発揮するのは、業務システムや基幹システムのように、長く保守し続ける前提の開発です。クラスの責務分割を初期に誤ると、後から機能を足すたびに影響範囲が広がり、改修コストが膨らみます。とはいえ、業務の要求を保守しやすいクラス構造へ落とし込むには、オブジェクト指向設計とドメインの理解の両方が要る仕事です。社内に設計を主導できる人材がいない、既存システムのクラス構造が複雑で手を入れづらい、といった場面では、外部の伴走が歯止めになります。一創では基幹システム開発として、業務要求をクラス設計や機能構造へ整理する要件定義から、設計・実装・運用までを一貫して支援しています。図を描く技術だけでなく、変更に強い構造を業務要求から導く設計まで含めた伴走が一創の強みです。
よくある質問
クラス図の理解と実務でつまずきやすい点を、5つの質問に絞って整理します。
クラス図とER図の違いは何ですか?
表す対象が異なります。クラス図はオブジェクト指向における「クラス」を単位に、属性・操作・クラス間の関係を表す図で、データと振る舞いの両方を扱います。ER図はデータベースの「テーブル(エンティティ)」を単位に、項目とテーブル間のリレーションを表す図で、操作は扱いません。設計をコードのクラス構造で考えるならクラス図、データの永続化構造で考えるならER図、という使い分けになります。両者は似た形に見えますが、目的の層が違います。
集約とコンポジションはどう使い分ければよいですか?
部分が全体なしに存在できるかで判断します。全体が消えても部分が別の場所で意味を持つなら集約(白抜きのひし形)、全体が消えると部分も存在意義を失うならコンポジション(塗りつぶしのひし形)です。「部署と社員」は社員が別部署へ移れるので集約、「注文と注文明細」は注文が消えれば明細も無意味になるのでコンポジションが向きます。迷う場合はまず関連で描き、従属が明らかな箇所だけコンポジションに変える進め方でも実務は回ります。
クラス図の多重度はどう決めればよいですか?
片方のクラスから見て、もう片方がいくつ対応するかを、業務のルールから決めます。1 はちょうど1つ、0..1 は0または1、1..* は1つ以上、* は0以上を表す記法です。「1人の利用者は複数の注文を持てるが、1件の注文は必ず1人の利用者に属する」といった業務ルールを、そのまま両端の数字に落とし込みます。多重度を曖昧にすると、必須・任意やデータの重複可否がぶれ、後のテーブル設計で手戻りが起きます。
クラス図はどのツールで作成できますか?
作図に特化したツールとして、draw.io、Lucidchart、astah、Visioなどが挙げられます。テキストから図を生成するPlantUMLやMermaidも使え、Gitでのバージョン管理と併せて運用できるのが強みです。仕様変更が頻繁で図を実装と同期させたい場合はPlantUMLやMermaid、見た目を細かく整えたい場合はGUIの作図ツールが向きます。チームの運用方針(コードで管理するか、図として管理するか)に合わせて選ぶのが実際的です。
クラス図に処理の流れは書けますか?
書けません。クラス図はシステムの静的な構造、つまり「どんなクラスがあり、どうつながるか」を表す図で、処理の順序や条件分岐は表現の対象外です。処理の流れを時間軸で表したい場合はシーケンス図やアクティビティ図を使います。クラス図で構造を固め、その構造がどう動くかを別の図で詳細化する、という役割分担が基本です。
関連記事
- オブジェクト指向とは:クラス図が前提とするカプセル化・継承・ポリモーフィズムの考え方
- ユースケース図とは:同じUMLで機能の輪郭を洗い出す図との役割分担
- システム開発の工程とは:クラス図を作る設計がどの工程に位置づくかの全体像
- 外部設計とは:クラス図が成果物となる設計工程の内訳と承認観点
- Mermaid記法の使い方:クラス図をコードとして描き、差分管理する手法