連載

【改訂版】初歩のUML

第2回 クラス図の詳細化とその目的


萩本順三
株式会社豆蔵
2003/2/11

 今回は、前回から引き続きクラス図の説明を行いながら、オブジェクト同士の関係(関連)をより詳しくモデリングしていきましょう。今回のサブテーマは、「モデル詳細化の本質的な意味を理解する」ということです。それってどういう意味? という声が聞こえてきそうですね。この解を知りたい人は、これからも連載をしっかりとお読みください(笑)。クラス図はUMLの中で最も重要なダイアグラムです。慌てず、焦らず、ダイアグラムの意味する本質について、じっくりと見極めていくことがモデリング習得の王道です。

関連名とロール名

 クラス図の関連線の中央に、関連名を記述することができます。関連名とは、クラス間の何らかのつながりに、一定の意味付けを行うために使います。例えば、図1は前回紹介した社員と会社の関連に「働く」という関連名を付けています。

 ロール名は、関連におけるそれぞれのオブジェクトの役割(ロール)を示すものです。例えば、社員から見て、会社は雇用者という役割を持っています。一方、会社から見て、社員には従業員という役割があります。

図1 関連名とロール名を付加する

(注1)前回は説明しませんでしたが、クラス表記の操作については、文字の後方に括弧“()”を付けます。
(注2)青色で表現している引き出し線と文字は、図を説明するための記述です。本来、クラス図には含めませんのでご注意ください。

関連名とロール名の必要性

 ここで、関連名やロール名はなぜ必要なのか考えてみましょう。もし、関連名やロール名の記述ができなければ、会社と社員の間には「何らかの関係がある」という意味しか表現できません。関連名、ロール名は、2つのクラスから作り出されるオブジェクトの実際の関係(リンクといいます)の意味を明確にします。漠然とした関係ではなく「どのような結び付きがあるのか」という関係に対して、何らかのスコープをかけるのが関連名なのです。関連によって結び付けられているクラスの間でやりとりされる情報交換が関連名によって、ある程度限定されることになります。

 関連と関連名をイメージで説明すると、関連は、オブジェクト同士がメッセージを交換するための太いパイプ(リンク)と考えてください。そして、関連名を付けることは、小さなパイプに取り替えることです。そうすることで、その中で交換されるメッセージの特性を絞り込むことができるため、モデルとして分かりやすくなるのです(図2)

図2 モデル図における関連名の役割

 関連名の右側に付いている三角形の矢印は、関連名の意味する方向を示しています。これは意味の概念的な方向性を示すものであり、実装におけるアドレス参照の方向ではないので注意してください。これは、関連名を付ける時であっても省略することもできます。

 ロール名は、オブジェクトの関係において相手側のオブジェクトの立場を役割として示すものです。このように相手側の役割が明確になれば、関連における相手側のオブジェクトの使われ方が明確になり、相手側となるクラスの、どのような操作を使うのかがモデルから予想できます。

  ロール名は、クラスがいくつかの役割を持っているとき、その役割の中の1つをロール名として表すときに使われます。もしも関連相手のオブジェクトの役割名が、クラス名となっている場合は、あえて表す必要はありません。

 このように関連名とロール名は、関連線を補足しモデルの意味を深める際に役立つものです。両者は、必ず必要というものではありません。関連名、ロール名、両方省略することもあります。また、どちらかを記述するだけで十分なこともあります。  

(注3)
 ここで関連名とロール名の誤った使い方について説明しておきましょう。問題領域をモデル化する際に、その問題領域の中でオブジェクト同士が協調動作する際の一側面(1シーン)だけに着目しすぎて関連名を付けてしまうと、問題領域の全体をモデル化した汎用的なクラス図というよりも、問題領域のあるシーンだけを想定したクラス図ということになってしまいますので注意しましょう。そのようなクラス図には、クラスの操作名のような関連名が付けられていることがよくあります。そのようなクラス図は、クラス図というよりも限りなくオブジェクト図に近いクラス図になってしまいます。もちろん、問題領域が非常に複雑な時、あるシーンを想定したクラスだけを抽出し、クラス図を書くという目的なら問題ありませんが、そのようなクラス図をたくさん作ってしまうと、問題領域の本質的なモデルを見失うことになってしまいますので注意しましょう。

関連の方向性について

 図2の関連をパイプで表現している箇所をよくご覧ください。パイプの中を通っているのはオブジェクトのメッセージです。この図ではメッセージは双方向にやり取りされています。このように関連を通るメッセージはデフォルトでは双方向性を持っています。なぜならば、クラス関連によって実際に作られるインスタンスのリンクは概念的には双方向性を持っていると考える方が自然だからです。しかし、設計になってくると無駄なインスタンスのリンクを取り去る必要もでてきます。このように、関連の方向性を片方向にするには、関連の線に矢印を付けることができます。このことをナビガビリティと呼びますが、この詳しい説明については連載の後半で行います。

集約はモデルの読み方にヒントを与える

 集約(aggregation)は、「全体−部分」を示すもので、関連の一種と見なすことができます。図3をご覧ください。集約はひし形で表され、会社(全体)は社員(部分)で構成されているという関係構造を意味しています。図1よりも、会社と社員の関係に全体と部分という意味が付加されたことでモデルの示す意味が分かりやすくなったと思いますが、いかがでしょうか?

 集約によって、モデル構造を全体-部分として見ることができます。これにより「部分を理解することで、全体の理解が増す」または「全体を理解することで、部分の理解が増す」というように、理解できているクラスから先に見て、理解できにくいクラスの理解度を促進することができるのです。このように集約は、モデルの読み方にヒントを与える重要なテクニックなのです。

図3 集約は、モデルを読み解くヒントを与える


集約の必要性

 集約も、関連名やロール名と同様に関連の意味を深める目的で使用されます。最終的なプログラミング・コード(以降、実装コードと表現します)にモデルを近づけるということだけが目的ではないことに注意しましょう。結果的に実装を示唆するという効果は確かにあります。しかし、関連を集約にするか否かという判断は、どういう実装にするかという観点で判断するのではなく、どちらにすればモデルが分かりやすくなるかで判断しなければなりません。

限定子は相手のオブジェクトを特定する

 限定子も関連の意味付けを深めるためのものです。図4をご覧ください。限定子は、会社クラスの右側にくっついている長方形で表します。中に社員番号と書いてありますね。限定子は、関連する両者のクラス間において、片方のオブジェクトから相手オブジェクトを特定(または何個かに限定)するために必要となる相手側のキーを記述します。

 図4の会社オブジェクトから見て、相手側の社員オブジェクトを特定するキーとは何でしょうか? もちろん社員番号ですよね。よって、会社クラス側に社員クラスとの関連線に限定子「社員番号」を付与します。

 限定子を使うことによって、自クラスが、関連先の相手と、どのようなキーで結び付いているのかがモデル上明確になります。図4では、社員クラスの多重度が1になっていますが、これは会社クラスの社員番号という限定子によって関連の相手側の多重度が1に限定されたことを意味しています。

 限定子は、相手側の属性(キー)となるものです。限定子を使うと、とても分かりやすくなるのですが、初心者にとっては少々難しいかもしれません。

 モデルを共有するチーム全体でこの限定子の意味が理解できていないなら、使わない方がよいでしょう。モデルはチームの成長の度合いに合わせて、分かりやすい記法を選ぶことも重要です。

図4 限定子

 関連の相手側の多重度が1にならない限定子も可能です。例えば社員番号の代わりに部門コードを限定子として使用する場合、部門コードで限定(つまり部門に所属する)される社員は複数人となります(図5)。このような使い方は、モデル上、関連に付与された限定子のモデル上の意味と必要性が分かりづらく、あまりお勧めしたくはありません。


図5 限定子(部門コード)


モデルを詳細化する目的は何か?

  今回は関連を詳細化するための表記方法をまとめてご紹介しました。さて、このようにモデルを詳細化する目的とは何でしょうか? このことをいま一度再考してみましょう。

 モデルを詳細化する目的は、モデリングの対象となる問題領域について理解を深めることにあります。そのことが結果的にモデルを実装コードに近づけることになる場合もありますが、そうでないこともあります。

 モデルを実装コードに近づけるとは、モデルから実装コードが一意に生成できるかどうかということです。クラスの属性の型や操作の引数や戻り値を明確にするような詳細化は、モデルを実装コードに近づけるための詳細化なのです。

 しかし、今回取り上げた関連の詳細化については、モデルを実装コードに近づけるような詳細化とは異なるものです。例えば、関連の線だけのものと、関連の線に集約をつけたものを実装コードに落とす際に明確な違いはありません。あくまで、分析・設計時にモデルの対象となる問題を深く理解させることが、今回取り上げた、モデルの詳細化の主たる目的です。

図6 モデリングの詳細化(理解目的、実装目的)

 例えば、業務分析時には業務の本質的な概念構造を理解するために、要求分析時には要求の理解を促進するために、ソフトウェア設計時には設計アーキテクチャの理解を深めるために、モデルの意味付けを詳細化するわけです。

 ただし、集約などのモデルを詳細化することで実装コードを示唆する効果もあるのは事実です。例えば、C++などメモリ管理を行う必要のある言語では、オブジェクトのライフサイクルを管理するオーナーを集約から想定することもできるでしょう。しかしながら、そのような観点で集約などを使っていると、理解のためのモデルの本質を見失ってしまうことになるでしょう。

(図7) モデリングの本質的な効果はモデルの対象となる問題を深く理解すること


クラス図を書く意味を理解する

 クラス図によるモデリングは、対象物に対する本質的な意味概念の静的な構造に着目して、その構造を理解するために使用します。そのために、対象となる問題の中に潜む動的な操作の流れをモデルとして表していません。動的側面からモデル化するものとして、シーケンス図、コラボレーション図、状態図などがあります。また、ソフトウェアに対する要求とその流れをとらえるのがユースケースモデルです。これらの表記法についても重要なものから順にこの連載で取り上げていきます。

 クラス図によるモデリングによる恩恵は、開発チームやユーザーの間で、対象問題の中から、最も重要で、かつ安定した概念の構造をオブジェクト・モデルとして共有できることです。これによって、ソフトウェア開発のプロセスの中で最も重要といえる「要求」、「目的」、「クラスデザイン」などを、変化の少ない静的な構造としてチーム全体で認知することができるようになります。開発に参加するメンバ全員で、仮想世界に作り上げた安定したモデルを共有し認知することは、とても大切なことなのです。

 このような理由からクラス図を評価する際に、いかに分かりやすいかということも評価のポイントとなります。よって、理解しやすいように詳細化をしないシンプルなモデルにしておくこともよくあることです。これは、従来の実装コードをすべて生成しようとするCASEツールとは相反します。

 安定した概念モデルを共有・認知することこそ、UMLを使ったモデリングの本質なのです。いかがでしょうか? UMLを単なるソースコード自動生成CASEツールの表記法だと思っている方も多かったのではないでしょうか?

 そうです、UMLは人が思考を整理するためのツール(言語)なのです。人しかやれないモデリングを支援する言語なのです。そう考えはじめるとUMLの重要性が単にプログラミングの世界だけにとどまらず、ビジネス・モデリングの世界に広がっている理由がお分かりになるでしょう。

 では、今回はこれでおしまいです。次回は、今回に引き続き、クラス図について説明します。次回もモデリングの不可思議な世界に、皆さんをご招待しましょう。どうぞ、お楽しみに!!

IT Architect 連載記事一覧

この記事に対するご意見をお寄せください managemail@atmarkit.co.jp

「ITmedia マーケティング」新着記事

2023年のSNS炎上総数は189件、炎上元の媒体1位は「X」――コムニコ「炎上レポート」
コムニコが「炎上レポート」2023年版を公開しました。

今度の「TikTok禁止」はこれまでとどう違う?
米国ではまたしてもTikTok禁止措置が議論されている。これまでは結局実現に至らなかった...

「ゼロクリック検索」とは? SGE時代の検索の変化と5つの対策を解説
SEO専門家やマーケター、そして情報を求める人々にとって、「ゼロクリック検索」はどのよ...