初心者が学ぶUMLの基礎~クラス図、表記法編~

2025/07/13

UML

 前回の記事でUMLの概要について勉強しました。

前回紹介したこの書籍にも記載がありましたが、UMLは膨大な仕様書があるためすべての仕様書を理解するのは現実的ではないです。すべてを理解することに時間をかけてしまうと開発効率を上げたいという本来の目的とずれてしまいます。
今回はUMLで定義されている構造図の中でよく使われているクラス図について勉強します。クラス図と言っても膨大な量があるため、ここではクラス図の概要と表記方法に焦点を当てて整理していきたいと思います。

クラス図概要

クラス図の目的はシステムの静的な構造を表現します。クラスの情報やクラスの関係から、システムの静的な構成を可視化していきます。

クラスとはオブジェクトの情報を抽象的に定義したものです。前回の記事でタイプとインスタンスの例で紹介しましたが、たい焼き機とたい焼きの関係のようなイメージです。(クラス(型)がたい焼き機でオブジェクト(実態)がたい焼き)

例えば車とメーカというクラスがあったとすると下記のような例になります。
クラス(型)オブジェクト(実態)
フィット、ヤリス、マーチ
メーカーHonda、Toyota、Nissan

クラス図とは上記のクラスの情報やクラスの関係からシステムの静的な構成を表現するための図になります。クラス図は静的な構成を表す主要な図なので、クラス図が完成すればプログラムの骨組みが見えてきます。

クラス図の表記方法

クラスは長方形の3段構成で表記し、上段にクラス名、中段に属性、下段に操作を配置します。例えば車クラスを作るとすると下記のようになります。(Draw.ioの操作に慣れることも加味してDraw.ioで前回紹介したメモを使って表現してみました。)


次にそれぞれの項目について説明してみます。

クラス名

これは紹介する必要がないかもしれませんがクラスの名前です。場合によっては前回紹介したステレオタイプも併記して表現する場合もありそうです。

属性

属性(Attribute)はクラスが持つ特性の事になります。例えば車クラスの場合では排気量や乗車定員数は各車両で異なりますが、すべての車両が持つ情報のため、クラスの属性として定義します。(電気自動車は排気量無いという野暮な指摘はしないでください。。。あくまで例なので)

構文としては下記のようになります。(可視性については後ほど紹介します。)
構文
可視性 属性名 : 型 =初期値

型は整数や文字列など、属性がどのような性質のデータかを示すものです。初期値はシステム内の初期段階で保持する値です。

例としては先ほどの図でも紹介したものですが、補足を加えると以下のようになります。
UMLにおける属性の例

操作

続いて操作(Operation)についてです。操作とはクラスが持つ処理の事です。例えば車クラスの場合、加速するや減速するなどが操作にあたります。

構文としては次のようになります。
構文
可視性 操作名 (引数 : 型, …) : 戻り値の型

引数:型は処理に必要なデータのデータ名とその型です。戻り値の型は処理終了後に呼び出し元に戻すデータの方です。引数:型、戻り値の型は省略することが出来ます。
例としては先ほど紹介したものですが、補足を加えると以下のようになります。
参考にした書籍では制約の記載はなかったのですが、前回学んだ制約も使ってみて表現してみました。戻り値は速度をイメージして整数としてます。

可視性

続いて先ほどから何度か登場している可視性について紹介します。可視性()とは属性や操作に対して、システム内におけるアクセスの可能範囲を定義するする要素です。可視性を定義することで属性や操作の責任範囲を明確にすることができます。
可視性は全部で4種類あり、下記の表のとおりです。
記号表現意味
public全てのクラスからアクセス可能
private自クラスのみアクセス可能
#protected自クラスと継承されているクラスからアクセス可能
package同一パッケージ内のクラスからアクセス可能

関連

2つのクラスが何かしらの関連を持っている場合、関連(Association)として表すことが出来ます。
関連を表現するには2つのクラス間を実線で結び、実践の中央部に「関連名(Association Name)」を配置します。

例えば次の例では「モーター」と「タイヤ」の間に「駆動する」という関連があることが分かります。

この例では関連名の横に▲が付いていますが、▲が付いている場合は関連を読む方向を表します。この例では「モーターはタイヤを駆動する」という風に読みます。
(この記載方法は右記文献にて紹介されてましたUML2 表記法ガイド Kindle版)

誘導可能性

関連は通常、双方向性を持っています。先ほど▲で表記した例では双方向性が無いですが、例えば最近の車はパーソナルデータを持っており、人はそのデータを知っているし、車もその情報を保持しているなどの場合は双方向のデータとなると思います。
少し話がそれてしまいましたが明らかに一方のオブジェクトからもう一方のオブジェクトのにしかデータを送らず、逆は行われない場合は関連に矢印と×印をつけることで関連の方向性を明確にします。この方向性を「誘導可能性(Navigability)」として表します。


多重度

関連のあるクラス間において一方からもう一方のクラスを見たときに依存しうる数値を多重度(Multiplicity)として表します。多重度は下記のようにクラスの実線の両端に配置して表現をします。

下記図では車クラスからToyotaクラスを見たときの多重度は1です。
つまり、この車クラスは常にToyotaに所属する(Toyota車である)ことを意味しています。

まToyotaクラスから車を見た時の多重度は「1...*」となってます。これはToyotaは1つ以上の車がある(複数車種がある)ことを意味してます。

多重度は他にも下記のように記載することが出来ます。
多重度意味
11のみ
0以上
0.. *0以上
1.. *1以上
0..10 or 1
5..85 ~ 8
1,3,51 or 3 or 5
1,4..71 or 4~ 7

関連端名

関係のあるクラス間において、一方からもう一方のクラスを見た時の役割を関連端名として表します。関連端名(Association End Name)は下記のように2つのクラスの両端に配置することが出来ます。
例えば下記の例では車クラスとToyotaクラスには「所属する」という関連があります。

「Toyota」クラスから「車」クラスを見ると「Toyota」に所属する「所属車種」となり、「車」クラスから「Toyota」クラスを見ると車が所属する「所属メーカ」となります。


汎化

続いて紹介するのは汎化です。汎化(Generalization)はいろいろと調べた結果、一般化するみたいなイメージでとらえるとよさそうです。逆に一般的な概念を元に具体化することを特化と言います。

あるクラスとそれを汎化したグラフやあるクラスとそれを特化したクラスの関係を汎化関係とも言います。

汎化関係において、より一般的な概念を表すクラスをスーパークラス(Super Class)といい、より具体的な概念を表すクラスをサブクラス(Sub Class)と言います。

用語だけだとわかりにくいので以下に具体例を示します。下記の図を見ていただくとわかりますが、汎化は白抜きの三角形がついて実線で表します。


汎化関係はis-a関係やa-kind-of関係とも呼ばれ、二つのクラス名を 「a kind of」や「is a」を用いて違和感ない文章を作ることができます。

例えば上記の例では「ガソリン車 is a kind of 自動車 = 電気自動車は自動車の一種である」や「ガソリン車 is a 自動車 = ガソリン車は自動車である」でも意味が通じます。

集約

次に集約(Aggregation)を紹介します。集約は2つのクラスに「全体と部分」の関係がある場合に使用します。集約は「全体」側のクラスに白抜きのひし形をつけて表記します。

具体的な例を書き図で示します。この例では車にはタイヤが含まれているということを示します。




この後紹介するコンポジションに比べて結び付きが弱い場合に使っていそうです。
例えば車を買い替えてもタイヤサイズが合えば買い替え後の車でも使用することができる場合などです。

コンポジション

コンポジション(Composition)は集約の一種です。「全体側」のインスタンスが「部分側」のインスタンスを所有していることを表します。先ほどの集約と異なり、結びつきが強い場合に使います。

コンポジションも集約と同じで「全体」側のインスタンスにひし形を付けますが、黒塗りのひし形になることが差分です。

例えば下記図のように自動車とエンジンの関係などです。自動車が消滅した(買い替える)際にエンジンごと取り外すというのはなかなかしないですよね?(車と一緒にエンジン載せ替えが当たり前の強い人は除きますが...)





依存

依存関係はあるクラスが変更された場合に他のクラスが影響を受けるような関係です。例えばあるクラスが別のクラスの操作に利用されたり、影響を受けたりする関係の場合、依存を使用します。コンポジションや集約に比べて関係の強さは弱いです。

この依存は私がイメージができなかったため、公式の資料も参照しました。

つたない英語力ですが、公式のドキュメントを確認すると依存(Depandencies)はモデル間のサプライヤーとクライアントの関係を示すという文言があります。

例えば下記が自動車工場と自動車の例です。点線の矢印が依存を表しており、この例は自動車工場がステレオタイプのInstance(自動車工場クラスが自動車クラスのインスタンスを生成する操作)を表現してます。

サプライヤーとクライアントの関係でいうと自動車がサプライヤー(供給される側)で自動車工場はクライアント(供給する側)を意味してます。この時自動車クラスはあくまで定義するだけ(設計図があるだけ)です。設計図を基に自動車工場が自動車を作るため、自動車の設計情報が変わると(例えば乗車定員数が変更されて椅子の数が増えるなど)自動車工場側にも何かしらの影響を与えてしまいます。

逆に工場側の修正は自動車側には影響は与えません。例えば工場が拡張されたり、製造工程の順番が変わっても最終的に作られる自動車は同じなので影響は与えません。
(実際の工場だと順番を変えるとラインタクトが...とかあるかもですが、作られる自動車という観点では変わりはないです。)

インターフェース

最後に紹介するのはインターフェース(Interfase)です。インターフェースとはクラスが実現しなければいけない操作のみが定義された特別なクラスです。インターフェースは「何を提供できるか」を宣言するだけで、どのように実現するかは意識せずに記載します。

インターフェースは操作の定義のみが記載されているので、操作の具体的な実現手段はサブクラスで記載します。インターフェースは頭に白抜きの三角形が付いた破線で表します。

具体的な例を電気自動車の充電機能で見てみます。

電気自動車に重要な機能として充電機能が必要です。電気自動車に乗ったことがある人はご存じだと思いますが、充電するにしても大きく普通充電:家庭用のコンセントからの充電と急速充電:商業施設などにある急速充電の設備を使った充電の2つがあり、この2つの充電を用いて電気自動車の充電機能を実現させてます。

クラスが外部に提供する機能の場合、提供インターフェースといい棒のついた球(ロリポップ)で表すこともできます。

逆にその機能を使う側のクラスを要求インターフェースを使って表現することができます。要求インターフェースは棒のついた半円(さすまた/ソケット)で表すことができます。例えば下記図は電気自動車が充電機能を要求するので要求インターフェースを使って下記のように表現します。

まとめ

今回はクラス図の表記について勉強をして整理しました。UML(というかオブジェクト指向?)は独特の表現が多く、自分が正しく理解できているかが怪しいですが、まずは自分の理解を整理してます。もし、認識が違うものがあればご指摘していただけると幸いです。







自己紹介

はじめまして 社会人になってからバイクやプログラミングなどを始めました。 プログラミングや整備の記事を書いていますが、独学なので間違った情報が多いかもしれません。 間違っている情報や改善点がありましたらコメントしていただけると幸いです。

X(旧Twitter)

フォローお願いします!

ラベル

QooQ