2003/3/4今回と次回はクラス図を中心に、少しだけ高度なモデリングの考え方について取り上げていきます。今回のメインテーマは、関連クラスと集約、コンポジションについてです。裏のテーマは、「モデルはモデリングの目的を明確にすることによって初めて価値が生まれることを知る」です。それは本号をじっくり読みながら、じんわり味わってください。関連クラス(社員と会社、関連クラスの実装)図1のクラス図は、第1回「まずはUMLのクラス図を書いてみよう」の「関連の多重度」の中で、誤った多重度として取り上げたものです。この図は、複数の会社に所属する社員がいるという意味がありました。この意味を深く考えてみると、このクラス図にはもっと本質的な問題点があることが分かります。複数の会社に所属する社員モデル社員と会社の関連を深く考えるため、図1に主たる属性を入れてみました(図2)。同時にこのクラス図のオブジェクト図も示しています。図2のオブジェクト図を見てください。山田さんは@ITとBeanStoreという2つの会社に所属していますよね。e-mailアドレスなどはBeanStore社と@IT社それぞれになければいけないように思えるのですが、それがこのモデルでは表現できていません。オブジェクト図で分かるように、BeanStoreインスタンスと@ITインスタンスからリンクされている山田インスタンスは1つしかないからです。このように考えると、このクラス図は、複数の会社に所属する社員のモデル化には適さないということが分かるでしょう。この問題をイメージ図として表すと図3のようになります。この図をよく見てください。e-mailアドレスは、BeanStoreインスタンスとのリンク(インスタンスとインスタンスを結ぶ線のこと)に付いているものなのです。@IT社用のものは、@ITインスタンスと山田インスタンスとのリンクに付いています。これらは、2つのインスタンスが関係を持つ際に、その関係に付属している属性ということになります。このようなインスタンス同士の関係に付属する属性のまとまりを表現する方法として、関連クラスがあります。図3を関連クラスで表現すると図4のようになります。図4のように関連クラスは、クラス間の関連の線に破線によって結びます。ちなみに関連クラスは、そのままではJava言語による実装はできません。よって、普通の関連に変える必要があります。このことはJava言語によるUMLマッピングの説明の際に取り上げる予定です。関連クラスモデリングの目的を考えるいかがですか。関連クラスはお分かりになりましたでしょうか。ここで、図4はどんな目的で作ったクラス図なのかということを考えてみましょう。このモデルは、複数の会社に所属する社員がいるという現実について、理解・表現を行うために書いたのであれば、有効といえます。ソフトウェアシステムを開発するために作成した部分的なモデルということでしたら少々問題があるかもしれません。どのようなシステムにこのモデルが必要とされるか、明確な意図が表れていないからです。系列会社の社員を管理する社員管理システムというものがあるとするならば、このモデルは正しいということになるでしょう。複数の会社に顧客を持つ弁当屋さんのシステムのモデルとしてはどうでしょうか。この場合、社員クラスというのは適切ではありませんよね。顧客クラスという名前にすべきでしょう。顧客管理システムが顧客を会社の社員番号で管理するのはナンセンスです。このクラス名は、顧客番号ということになります。顧客番号という性質から考えると、特に会社ごとに顧客番号を変える必要性はまったくありませんので、顧客クラスの属性とすべきでしょう。e-mailアドレスも同様に単に連絡先ということだけでしたら、1個あればいいですし、連絡先という属性が自然ですね。いうことで、弁当屋さんの顧客管理システムということになると図5のようになります。弁当屋さんの顧客管理システムこのように、クラス図によるモデリングは、モデリングの目的や対象を明確に持たない限り、そのモデルが正しいかどうかが分からないものなのです。目的が異なるとクラス名や属性が異なってきます。よって、モデリングを行う際には、目的を明確に持つよう心掛けてください。今回のように、問題領域を単に理解するという目的でモデリングをすることは問題ではありません。このような目的で作成されたモデルは、ソフトウェアシステムのモデルとしては適切ではないのです。ソフトウェアシステムのモデルならば、図5で示した弁当屋さんが顧客を管理するシステムのように、システム化するうえで明確な目的があるはずだからです。このような目的を明確にしてモデリングを行うことができるようになれば、プロフェッショナルなモデラーに一歩近づくことができます。集約の利用パターンを考える第2回「クラス図の詳細化とその目的」で集約の説明をしましたが、「集約と関連の使い分けをどうしたらよいか」という質問をよく受けます。いうときは、「集約は、全体-部分の関係があるときに使用します。集約と関連どちらにすべきか悩んでしまうこともあります。この2つの意味の違いを考えすぎるとよくないですよ。」などとあっさりと説明するようにしていたのですが、最近では次の2つの定義を説明するようにしています。これはあくまで私流の定義ですが、おそらく皆さんにも参考になると思います。◆利用パターン1(物理的な全体-部分構造)モデリング対象である実態を理解するために、物理的に1つのものを「全体と部分」に分けたものです。車の構成要素を分析したモデルを図6に示します。これは、車を分析して構成要素を抽出して示しています。物理的に1つのものを分解することで理解を深めるために集約を使用した例です。この図では運転手については、車の部品ではありませんので関連として表しています。このように物理的に1つのものを理解するために「全体と部分」に分けたものをここでは「物理的な全体-部分構造」と呼ぶことにします。車の構成要素モデル次は、クレジットカードの請求書をモデリングしてみましょう。実は私もそうなので、このモデリングもあっさりとやることにしましょう(注)。図7は請求書モデルです。これは、請求書は1個以上の明細からなるということを示しています。属性など細かなことは省略します。これも1つのものを分解して理解するためのモデルですが集約を使うことができます。(注)この例は、業務モデリングとしてはあまりにもシンプルすぎますので、その言い訳です。請求書の構成要素モデル◆利用パターン2(論理的な全体-部分構造)論理的に「全体と部分」の意味を持つものです。会社クラスと社員クラスの関係として会社は社員によって構成されるという概念から集約として表すことができます。このようにして使う集約は非常に曖昧(あいまい)で、集約にすべきか、関連にすべきか、悩むこともあります。実世界の会社と社員という概念はそれぞれ自立して存在しているという側面もあるからです。ここでは、これを「論理的な全体-部分構造」とします。このような「論理的な全体-部分構造」を皆さんが発見した場合、全体-部分という観点よりも、どちらかというとグルーピングしたいという目的で集約を使っていることが多いのではないでしょうか。何らかの論理的な意味からみて、グループ化する対象とされる対象を集約で結び、どちらが意味的な部分なのかを理解させるテクニックとして集約を使っているのです。関係を集約と関連で表しています。集約がつけられた方が、意味構造が分かりやすいですね。このようにモデルを分かりやすくするために集約を使っているわけです。「論理的な全体-部分構造」が多く見つかり、集約ばかりになってしまったときに、無意識に集約を関連に変える人も多いでしょう。「論理的な全体-部分構造」は問題をみる観点をちょっと変えるだけで、集約に見えたり関連に見えたりするため、都合の良い方に無意識に変えているように思えます。「論理的な全体-部分構造」の場合、集約にすべきか関連にすべきかが曖昧(あいまい)になってしまうのではないでしょうか。よって、このような「論理的な全体-部分構造」を見つけた場合、モデルとして分かりやすいかどうかで、集約と関連のどちらにするか判断されることをお勧めします。関連か集約かコンポジションとはコンポジションは、集約の一種です。2つのクラスの依存関係は、両オブジェクトのライフサイクル(生成と消滅)がほぼ一致する場合に使います。具体的にいうと先に挙げた集約の利用パターン1(物理的な全体-部分構造)のモデリング対象の実態が物理的に1つのものを理解するために「全体と部分」に分けたものに使うと分かりやすいです。請求書の構成要素モデル」をコンポジションで表したものです。このように、コンポジションは、集約マークを黒く塗りつぶしたものを使います。コンポジションについても、集約かコンポジションのどちらを使うかは曖昧(あいまい)です。「両オブジェクトのライフサイクルが同じ」「物理的に1つのものを分けた」ということを強調したいときに使ってください。Inc.著作権はアイティメディア株式会社またはその記事の筆者に属します。(著作権について)当サイトに掲載されている記事や画像などの無断転載を禁止します。@IT情報マネジメント」「JOB@IT」「@ITハイブックス」「ITmedia」は、アイティメディア株式会社の登録商標です。当サイトに関するお問い合わせは「@ITへのお問い合わせ」をご覧ください。