OOPでの関連付け、集約、および構成の説明

統一モデリング言語(UML)は、オブジェクト指向システムをモデリングするための事実上の標準です。UMLには、関連付け、集約、構成、依存関係、継承の5種類の関係があります。この記事では、これらの概念の最初の3つについて説明し、残りの概念は別のブログ投稿に残します。

オブジェクト指向プログラミングにおける関連

アソシエーションは、他の点では無関係なオブジェクト間の意味的に弱い関係(意味的な依存関係)です。アソシエーションは、2つ以上のオブジェクト間の「使用」関係であり、オブジェクトには独自の存続期間があり、所有者は存在しません。

例として、医師と患者の関係を想像してみてください。医師は複数の患者と関連付けることができます。同時に、1人の患者が治療または相談のために複数の医師を訪問することができます。これらのオブジェクトにはそれぞれ独自のライフサイクルがあり、「所有者」や親は存在しません。関連付け関係の一部であるオブジェクトは、個別に作成および破棄できます。

UMLでは、関連付け関係は1つの矢印で表されます。アソシエーション関係は、1対1、1対多、または多対多(カーディナリティとも呼ばれます)として表すことができます。基本的に、2つ以上のオブジェクト間の関連付け関係は、1つのオブジェクトが別のオブジェクトにメッセージを送信できるように、それらの間の通信パス(リンクとも呼ばれる)を示します。次のコードスニペットは、BlogAccountとBlogEntryの2つのクラスが互いにどのように関連付けられているかを示しています。

パブリッククラスBlogAccount

   {{

       プライベートBlogEntry [] blogEntries;

       // BlogAccountクラスの他のメンバー

   }

パブリッククラスBlogEntry

   {{

       Int32 blogId;

       文字列キャプション;

       文字列テキスト;

       // BlogEntryクラスの他のメンバー

   }

オブジェクト指向プログラミングにおける集約

集約は、2つ以上のオブジェクト間の特殊な形式の関連付けであり、各オブジェクトには独自のライフサイクルがありますが、所有権も存在します。集約は、典型的な全体/部分または親/子の関係ですが、物理的な封じ込めを示す場合と示さない場合があります。集約関係の本質的な特性は、全体または親(つまり所有者)が部分または子なしで存在できること、およびその逆であるということです。  

例として、従業員は組織内の1つ以上の部門に属している場合があります。ただし、従業員の部門が削除された場合、従業員オブジェクトは破棄されずに存続します。集計に参加しているオブジェクト間の関係を相互に関連付けることはできません。つまり、部門は従業員を「所有」できますが、従業員はその部門を所有していません。次のコード例では、BlogAuthorクラスとBlogAccountクラスの間に集計関係があります。

パブリッククラスBlogAuthor

   {{

       プライベートInt32authorId;

       プライベート文字列firstName;

       プライベート文字列lastName;

       // BlogAuthorクラスの他のメンバー

   }

パブリッククラスBlogAccount

   {{

       プライベートBlogEntry [] blogEntries;

       // BlogAccountクラスの他のメンバー

   }

集計は通常、中空のひし形の線を使用してUMLで表されます。アソシエーションと同様に、集約には、参加するオブジェクト間の1対1、1対多、または多対多の関係が含まれる場合があります。1対多または多対多の関係の場合、それは冗長な関係であると言えます。

オブジェクト指向プログラミングにおける構成

構成は、特殊な形式の集約です。構成では、親オブジェクトが破棄されると、子オブジェクトも存在しなくなります。構成は実際には強力なタイプの集約であり、「死」関係と呼ばれることもあります。一例として、家は1つまたは複数の部屋で構成され得る。家が破壊されると、家の一部であるすべての部屋も破壊されます。次のコードスニペットは、HouseとRoomの2つのクラス間の構成関係を示しています。

パブリッククラスハウス

{{

   個室ルーム;

   パブリックハウス()

   {{

       room = new Room();

   }

}

集約と同様に、構成も全体/一部または親/子の関係です。ただし、構成では、パーツまたは子のライフサイクルは、それを所有する全体または親によって制御されます。この制御は、直接または推移的のいずれかである可能性があることに注意してください。つまり、親が子の作成または破棄に直接責任を負う場合もあれば、すでに作成された子を使用する場合もあります。同様に、親オブジェクトは、子オブジェクトを破棄するために、コントロールを他の親に委任する場合があります。構成は、他のオブジェクトを所有するオブジェクトの端にある実線のひし形でオブジェクトを結ぶ線を使用して、UMLで表されます。

この関連付け、集約、および構成の関係についての説明が、これら3つの概念の違いを理解するのに役立つことを願っています。集約と構成はどちらも関連付けのサブセットであることを忘れないでください。集約と構成の両方で、あるクラスのオブジェクトが別のクラスのオブジェクトの所有者になることができます。また、集約と構成の両方で、子オブジェクトは単一の親オブジェクトに属します。つまり、所有者は1人だけです。

最後に、集約関係では、親オブジェクトと子オブジェクトのライフサイクルは独立しています。構成関係では、親オブジェクトの死は、その子の死も意味します。