クラス図(Class diagram)

クラス図について

クラス図とは

クラス図とは、クラスの構造や属性(データや処理の情報)、およびそのクラス間の関係性を表現する図のことです。
クラス図を記述することで、システムの静的な構造を図で表現することができます。


(備考)クラスとは

クラスとは、オブジェクトを生成するための設計図あるいはテンプレートに相当するものです。
クラスから生成したオブジェクトの実体のことをインスタンスといいます。
クラスには、クラス自身またはクラスのインスタンスが保持するデータと、データに関連したオブジェクトの振る舞いを記述します。


クラスの表記と構造

クラスの定義

UMLクラス図では、1つのクラスにつき1つの枠を用意し、その枠内に上段・中段・下段の3つの構成要素を設定します。
上段に「クラス名」、中段に「属性」、下段に「操作」をそれぞれ記入します。


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

クラス図の属性と操作には、可視性(アクセス修飾子)を定義できます。

  • 「+」全クラスからアクセス可能(public)
  • 「-」自分のクラス限定でアクセス可能(private)
  • 「#」自クラスと親子関係クラス限定でアクセス可能(protected)
  • 「~」同一パッケージ内のクラスのみアクセス可能(package)

クラス図は厳密に記述しなくてもよい?

クラス図は、オブジェクト指向言語の実装と非常に親和性が高く、メンバーやメソッドをソースコードにそのまま落とし込むことができます。
そのため、設計の意図が伝わることを優先して考え、ラフに記述したり、不必要な情報はむしろ書かないほうがよい場合などもあります。
実際のプロジェクトで利用していく中では、読みやすさや伝えわりやすさを優先して、仕様外の表記をしたり、自由なコメントを記述していることがよくあります。


関連(クラス間の関係性)

クラス図では、全てのクラスが関係性を持っており、互いに関連付けられています。
関連は、「has-a関係」と呼ばれる関係です。
これらの関連付けは、ユーザーがさまざまなエンティティ(実体)間の関連を十分に理解するのに役立ちます。

関連(association)

関連とは、クラス間の関係性を記述しています。
関連を表現するには、クラス間を線で結び、そこに関連名を付与します。


誘導可能性(navigate)

「誘導可能性」は、クラス同士のやりとりの方向性を表現します。
クラスの間に線を引いて、影響を及ぼす側に向けて矢印を書き、影響を与えられない方には線の上にバツ印を書きます。
誘導可能性が未定の場合には、記載しません。


上図では以下のことがわかります。
・運営からオーケストラは操作可能であるが、オーケストラから運営の操作は不可能である。
・オーケストラから楽団員は操作可能であるが、楽団員からオーケストラに対しては未定である。


多重度(multiplicity)

多重度とは、関連のあるクラス間において、Aクラスから見た場合のBクラスが存在しうる数です。

上図では以下のことがわかります。
・1つのオーケストラから見て、楽団員は1人以上いること
・1人の楽団員から見て、所属するオーケストラは1つであること。
・楽団員にはチューバ担当者が最大で2人(4管編成以上)、もしくは不在(1管編成)の可能性があること。

多重度の数字の意味は以下のようになります。

表記 意味
n 値の通り
"0..n" または "*" 0以上
"1..*" 1以上
"m..n" 少なくともm、最大n(m <= n)


集約とコンポジション

集約(Aggregation)とは

集約とは、「has-a関係 (もしくは A has a B )」ともいい、クラス間の全体と部分を表現するための表記です。
クラス間に強い結びつきはなく、全体クラスが消滅しても、部分クラスは生存し続けます。

例えば、オーケストラが解散してもヴァイオリニストは死にませんし、別のオーケストラで活動する可能性もあります。


コンポジション(Composition:合成集約)とは

コンポジションとは、所有者クラスと所有されるクラスなど、主従関係を明確に示すための表記です。
その関係は「part-of 関係 (もしくは B is a part of A )」と呼ばれます。
両者の関係に強い結びつきがあり、全体クラスが消滅すると、部分クラスも消滅します。

例えば、オーケストラが解散したら、そのオーケストラの楽団員という立場は消滅します。


汎化と特化

汎化(generalization)とは

汎化とは、具体的なクラスと具体的なクラスから抽象化したクラスの関係を示すための表記です。
つまり、いくつかのクラスに共通している事柄をまとめて、1つの別のクラスを作ることが汎化です。
(汎化と継承はほぼ同義です。ただし、厳密にいえば、継承は汎化の実現手段の1つです。)


親となるクラスを基本クラス(スーパークラス)と呼び、親を継承した子クラスを派生クラス(サブクラス)と呼びます。
上図では、弦楽器をスーパークラスと呼び、各楽器パートをサブクラスと呼びます。


特化(specialization)とは

特化とは、抽象的なクラス(汎化したクラス)から具体的なクラスを定義することです。
UMLで、特化を表す表記はありません。汎化の表記を見て、特化であることを把握します。


依存(dependency)

UMLの依存とは、クラス同士の一時的な利用関係のことで、クラス間の弱い関係性があることを表現します。
言い換えれば、オブジェクトが、あるオブジェクトを利用する関係を依存と呼びます。
※UMLの依存は、日本語的な字面とは意味が異なり、存在的な依存という関係性はありませんので注意が必要です。

依存の例として、ヴァイオリンを弾くヴァイオリニストと、ヴァイオリンの関係を表すクラスを考えます。
まず、ヴァイオリニストはヴァイオリンを弾きます。
そのために、インスタンス化されたヴァイオリンを引数にとり、そのヴァイオリンを弾くというメソッドを持ちます。
つまり、ヴァイオリニストはヴァイオリンを使用する形で依存関係にあるといいます。



インターフェースと抽象クラスについて

インターフェースとは

インタフェースとは、クラスが仕様を実現する上で必要な共通操作のみを定義したクラスのことです。
インタフェースには操作の具体的な処理は記載せず、具体的な処理は「サブクラス」で定義します。
このインタフェースとサブクラスの関係を「実現」と言い、下記のように矢印と点線で表現します。



抽象クラスとは

抽象クラスとは、抽象メソッドを1つ以上持つクラスを指します。
抽象メソッドは具体的な処理内容を記述せず、メソッド名や引数などの定義だけを宣言するメソッドです。
つまり、抽象クラスは、自身だけでは意味をもたず、サブクラスに継承されることで初めて機能します。


インターフェースクラスと抽象クラスの違い

抽象クラスは「ものを定義する」ために用いて、インターフェースは「ふるまいを定義する」ために用います。
抽象クラスはサブクラスが実装またはオーバーライドできる機能を作成できますが、インターフェイスでは機能を記述するだけで実装はできません。
(オーバーライドとは、親クラスのメソッドをサブクラスで書き換えることです。)



関連ページ