ガイドライン: 集約
トピック
集約は、モデル要素間のコンポジション関係をモデル化するために使用します。コンポジション関係には、次のようにさまざまな例があります。図書館には本があり、会社の部門は従業員で編成されており、コンピュータはいくつかのデバイスから構成されています。このような関係をモデル化するため、集約 (部門) には構成部分 (従業員) に対する集約関係があります。
集約を示すため、関連パスの集約 (全体) の側には中空の菱形を付けます。
例
この例では、顧客は住所を持っています。この 2 つのクラスは大きな全体の一部を表しているので、集約を使用します。また、同じように住所を持つものがほかにも多くあるので、独立したクラスとして住所をモデル化してあります。

集約オブジェクトは、ほかのオブジェクトを一緒に保持してもかまいません。
集約に対して 1 より大きな多重度が設定されている集約関係は共有関係と呼ばれ、集約を破棄しても部分は必ずしも破棄されません。つまり、共有関係の集約は、グラフつまり多数の根を持つ木を形成します。共有関係にある集約は、2 つのクラス間に強い関係がある場合に使用され、同じインスタンスが 2 つの異なる集約に参加できるようにします。
例
ある人が在宅ビジネスを行っているケースを考えます。人とビジネスはどちらも住所を持ち、実際のところそれは同じ住所です。住所は、人とビジネスの両方にとって不可欠な部分です。ビジネスが存在しなくなっても、できれば人は同じ住所に留まります。
また、この場合には共有関係にある集約から始めて、後で非共有の集約に変換することが可能であるということに注意してください。在宅ビジネスが成長して軌道に乗ったなら、いずれはビジネスを別の場所に移す可能性があります。その時点で、人とビジネスは同じ住所を共有しなくなります。その結果、集約は共有されなくなります。

共有関係にある集約の例
コンポジションは集約の 1 つの形態であり、部分に対する強力な所有権を持ち、部分の存続期間は集約と一致しています。集約側の終端 (この例では注文) の多重度は、1 を超えることはできません (つまり共有不可)。集約も変更不可能で、いったん設定するとリンクの変更はできません。つまり、コンポジット関係の集約は部分の「木」を構成し、根が集約で、「枝」が部分となります。
コンポジション集約は、集約側と部分側の間に強い相互依存関係がある場合、つまり部分がないと集約の定義が不完全になる場合に、「普通」の集約に対して使用する必要があります。次に示す例では、何の注文がなくても、注文項目があれば意味を持ちます (線項目など)。場合によっては、この相互依存関係は分析段階の初期段階で識別できますが (この例の場合のように)、通常は、自信を持ってこのような決定を下すことができるのは設計段階になってからです。
次に示すように、コンポジションを示すためには、関連パスの終端に塗りつぶした菱形を付けます。

コンポジション集約の例
例
この例では、顧客インターフェイスはほかの複数のクラスで構成されています。この例では、集約の多重度はまだ指定されていません。

顧客インターフェイス オブジェクトは、どのディスプレイ、レシート プリンタ、キーパッド、スピーカー の各オブジェクトが自分に属しているのかを知っています。
クラスのプロパティは、クラスが知っていることを示すものです。前記の顧客クラスの場合、顧客の住所は、例で示されているようにクラスとしてモデル化することも、クラスの属性の集合としてモデル化することも、どちらも可能です。クラスと集約関係または属性の集合のどちらを使用するのかは、以下のことに基づいて決定します。
- 「プロパティ」に独立した ID を設定し、複数のオブジェクトから参照できるようにする必要があるか。必要がある場合は、クラスと集約を使用します。
- 複数のクラスが同じ「プロパティ」を持つ必要があるか。必要がある場合は、クラスと集約を使用します。
- 「プロパティ」が、複雑な構造と自分自身のプロパティを持っているか。持っている場合は、クラス (1 つまたは複数) と集約を使用します。
- これ以外の場合には属性を使用します。
例
ATM では、システムが現在の顧客と顧客の PIN を追跡する必要があるので、顧客インターフェイスがこれを行うものと仮定します。この情報は、クラスの「プロパティ」として考えることができます。次に示すように、独立したクラスを使用してこれを実現できます。

集約を使用してモデル化したオブジェクト プロパティ
もう 1 つの方法として、次の例では、顧客インターフェイスが属性を使用して現在の顧客と顧客の PIN を追跡するようにモデル化されています。

属性を使用してモデル化したオブジェクト プロパティ
属性と、別のクラスに対する集約関係のどちらを使用するのかの決定は、表現する概念間の結合の度合いに基づいて行います。モデル化する概念が密接に結合している場合は、属性を使用します。概念が独立して変化する可能性が高い場合は、集約を使用します。
集約は、クラス間にコンポジション関係がある場合、あるクラスがほかのクラス群で構成されている場合、全体の枠組みから外れると「部分」が不完全になる場合にのみ、使用する必要があります。注文の場合を考えてみます。「空」であり、「何もない」状態にある注文には意味がありません。すべての集約について同じことが言えます。部門には従業員がいなければならず、家族には家族の構成員が必要です。
クラスがほかのクラスによって提供される枠組みの外側で独立したアイデンティティを持つことができる場合、またはクラスが大きな全体の一部ではない場合は、関連を使用する必要があります。さらに、不確かな場合には関連を使う方が適切です。集約は一般に明白なものであり、集約は明確化に役立つ場合にだけ選択します。集約の使用は、モデル化作業の成功に不可欠というわけではありません。
クラスが自分自身と集約関係になる場合があります。これは、そのクラスのインスタンスがそのインスタンス自体で構成されているという意味ではなく (これはばかげています) 、クラスのあるインスタンスが同じクラスの別のインスタンスから構成される集約であることを意味します。自己集約の場合、ロール名は関連の目的を区別するために必ず必要です。
例
製品クラスに関係する次の自己集約について考えてみます。

この例では、ある製品は別の製品で構成される場合があります。そのような場合、集約される製品のことを副製品と呼びます。この関連は、集約オブジェクトから副製品に対してのみ誘導可能です。つまり、副製品は自分がどの製品の一部なのかを知りません (副製品は多くの製品の部品だからです)。
|