UML における構成と集計の違いを理解するのに苦労しました。誰かが私にそれらの間の良い比較と対照を提供してもらえますか? また、コードでそれらの違いを認識したり、短いソフトウェア/コードの例を見たりすることを学びたいです。
編集: 私が質問する理由の 1 つは、私たちが職場で行っている逆の文書化活動のためです。コードを書きましたが、戻ってコードのクラス図を作成する必要があります。アソシエーションを適切にキャプチャしたいだけです。
経験則として:
class Person {
private Heart heart;
private List<Hand> hands;
}
class City {
private List<Tree> trees;
private List<Car> cars
}
コンポジション(人、ハート、手) では、「サブオブジェクト」 (ハート、手) は、人が破壊されるとすぐに破壊されます。
集約(City、Tree、Car) では、City が破棄されても「サブ オブジェクト」(Tree、Car) は破棄されません。
要するに、構成は相互の存在を強調し、集約では、このプロパティは必要ありません。
集約と構成の違いは、コンテキストによって異なります。
別の回答で言及されている車の例を見てください-はい、車の排気ガスが「それ自体で」立つことができるのは事実であるため、車と一緒に構成されていない可能性があります-しかし、それは用途によって異なります. スタンドアロンの自動車排気ガスを実際に処理する必要があるアプリケーション (カー ショップ管理アプリケーション?) を構築する場合は、集約が最適です。しかし、これが単純なレーシング ゲームで、車の排気管が車の一部として機能するだけであれば、構成は問題ありません。
チェス盤?同じ問題。チェスの駒は、特定の用途でのみチェス盤なしでは存在しません。他の企業 (玩具メーカーの企業など) では、チェスの駒をチェス盤に構成することはできません。
構成/集約をお気に入りのプログラミング言語にマップしようとすると、事態はさらに悪化します。一部の言語では違いに気づきやすい場合があります (「参照による」対「値による」、物事が単純な場合) が、他の言語ではまったく存在しない場合があります。
最後に一言アドバイスを。この問題にあまり時間をかけないでください。それは価値がありません。この区別は実際にはほとんど役に立ちません (完全に明確な「構成」がある場合でも、技術的な理由 (たとえば、キャッシング) により、それを集約として実装したい場合があります)。
コンポジションとアグリゲーションは関連の一種です。これらは非常に密接に関連しており、プログラミングに関しては、両者の間に大きな違いはないようです。これら2つの違いをJavaコードの例で説明しようと思います
Aggregation : オブジェクトは他の外部に存在し、外部で作成されるため、(たとえば) コンストラクターに引数として渡されます。例: 人 – 車。車は別のコンテキストで作成され、個人の所有物になります。
// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
private HttpListener listener;
private RequestProcessor processor;
public WebServer(HttpListener listener, RequestProcessor processor) {
this.listener = listener;
this.processor = processor;
}
}
構成: オブジェクトは、他のオブジェクトの一部としてのみ存在するか、他のオブジェクトの内部でのみ意味を持ちます。例: 人 – 心。心を作ってそれを人に渡すわけではありません。代わりに、人間が作成されたときにハートが作成されます。
// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
private HttpListener listener;
private RequestProcessor processor;
public WebServer() {
this.listener = new HttpListener(80);
this.processor = new RequestProcessor(“/www/root”);
}
}
ここで例を挙げて説明します集計と構成の違い
コンポジションは、子オブジェクトが親と寿命を共有することを意味します。集約はしません。たとえば、チェス盤はチェスの升で構成されています。チェスの升は盤がなければ実際には存在しません。ただし、車は部品の集合体です。車の排気ガスは、その時点で車の一部ではない場合でも、車の排気ガスです。
私が学んだ例は、指から手にありました。あなたの手は指で構成されています。それはそれらを所有しています。手が死ぬと指が死ぬ。指を「集約」することはできません。余分な指をつかんで、自由に手から付けたり外したりすることはできません。
ここでの値は、設計の観点から、別のポスターが言ったように、オブジェクトの寿命に関連していることがよくあります。顧客がいて、彼らがアカウントを持っているとします。そのアカウントは、顧客の「構成された」オブジェクトです(少なくとも、私が考えることができるほとんどのコンテキストで)。顧客を削除すると、アカウント自体には価値がないため、アカウントも削除されます。オブジェクトの作成では、多くの場合、その逆が当てはまります。Account は Customer のコンテキストでのみ意味を持つため、Account の作成は Customer の作成の一部として行われます (または、怠惰に行うと、Customer トランザクションの一部になります)。
他のオブジェクトを所有 (構成) するオブジェクトと、他のオブジェクトを参照 (集約) するだけのオブジェクトについて考えると、設計に役立ちます。オブジェクトの作成/クリーンアップ/更新の責任がどこにあるのかを判断するのに役立ちます。
コードに関する限り、多くの場合、見分けるのは困難です。コード内のほとんどすべてがオブジェクト参照であるため、参照されたオブジェクトが構成 (所有) されているか集約されているかは明らかではありません。
部分と全体の関連概念の集約と構成の違いについて、どれだけ多くの混乱が存在するかは驚くべきことです。主な問題は、(専門のソフトウェア開発者や UML の作成者の間でさえ) 誤解が広まっていることです。構成の概念は、全体とその部分の間のライフサイクルの依存関係を意味し、部分は全体なしでは存在できないというものです。しかし、この見解は、部分が全体から切り離され、破壊されても生き残ることができる共有不可能な部分との部分全体の関連付けのケースもあるという事実を無視しています.
UML 仕様書では、「構成」という用語の定義は常に共有不可能な部分を暗示してきましたが、何が「構成」の定義特性であり、何が単にオプションの特性であるかは明確ではありませんでした。新しいバージョン (2015 年現在) の UML 2.5 でさえ、「構成」という用語の定義を改善しようとした後でも、あいまいなままであり、共有不可能な部分と全体の関連付けをモデル化する方法についてのガイダンスを提供していません。部分を切り離すことができず、全体と一緒に破壊される場合とは対照的に、部分を切り離すことができず、全体が破壊されても生き残ることができる部分。彼らが言うには
複合オブジェクトが削除されると、オブジェクトであるすべてのパーツ インスタンスが一緒に削除されます。
しかし同時にこうも言っています。
パーツ オブジェクトは、複合オブジェクトが削除される前に複合オブジェクトから削除されることがあるため、複合オブジェクトの一部として削除されることはありません。
この混乱は、コンポーネントとコンポジット間のライフサイクルの依存関係を考慮していない UML 定義の不完全性を示しています。したがって、コンポーネントをコンポジットから切り離すことができず、コンポジットが破棄されるたびにコンポーネントを破棄する必要がある << inseparable >> コンポジションの UML ステレオタイプを導入することによって、UML 定義を強化する方法を理解することが重要です。
Martin Fowler が説明したように、構成を特徴付ける主な問題は、「オブジェクトは 1 つの構成関係の一部にしかなれない」ということです。これは、Geert Bellekens による優れたブログ投稿UML Composition vs Aggregation vs Associationでも説明されています。コンポジションのこの定義的な特性 (排他的、または共有不可能な部分を持つ) に加えて、コンポジションには、コンポジットとそのコンポーネント間のライフサイクル依存性も伴う場合があります。実際、そのような依存関係には次の 2 種類があります。
Person
との間の構成によって例示されます。Heart
心臓の所有者が死亡すると、心臓は破壊されるか、別の人に移植されます。Person
ですBrain
。要約すると、ライフサイクルの依存関係は構成の特定のケースにのみ適用されますが、一般的には適用されないため、定義的な特性ではありません。
UML 仕様には次のように記載されています。–<code>Engine 構成の例ではCar
、次の図に示すように、車が破壊される前にエンジンを車から取り外すことができるケースは明らかです。 -使用済み。これは、構成線の複合側の多重度が0 または 1であることによって暗示されます。
コンポジット側でのコンポジションのアソシエーション エンドの多重度は、コンポーネントが必須のコンポジットを持っている (コンポジットにアタッチする必要がある) かどうかに応じて、1 または 0..1 のいずれかになります。コンポーネントがinseparableである場合、これは必須のコンポジットがあることを意味します。
集約は、全体の部分を他の全体と共有できる、部分と全体の関係の意図された意味を持つ別の特別な形式の関連付けです。たとえば、コースは学位プログラムの一部でDegreeProgram
ありCourse
、コースは 2 つ以上の学位プログラム間で共有できるため (たとえば、工学の学位は Cコンピュータ サイエンスの学位を取得したプログラミング コース)。
ただし、共有可能な部分を持つ集約の概念は実際にはあまり意味がないため、実装には何の影響もありません。したがって、多くの開発者はクラス図で白いひし形を使用せず、単純な関連付けをモデル化することを好みます。代わりは。UML 仕様には、「共有集計の正確なセマンティクスは、アプリケーション領域とモデラーによって異なります」と記載されています。
部分が任意の数の全体に属している、またはそれらの間で共有されている可能性があるため、全体側での集合体の関連端の多重度は任意の数 (*) である可能性があります。
コード用語では、構成は通常、含まれているオブジェクトがコンポーネント*のインスタンスの作成を担当し、含まれているオブジェクトがそれへの有効な参照のみを保持することを示唆しています。したがって、親オブジェクトが逆参照されてガベージ コレクションされると、子も同様になります。
だからこのコード...
Class Order
private Collection<LineItem> items;
...
void addOrderLine(Item sku, int quantity){
items.add(new LineItem(sku, quantity));
}
}
は、LineItem が Order のコンポーネントであることを示しています。LineItem は、それを含むオーダーの外には存在しません。しかし、アイテム オブジェクトは注文どおりに構築されません。ショップに注文がない場合でも、必要に応じて渡され、存在し続けます。そのため、コンポーネントではなく関連付けられています。
* nb コンテナはコンポーネントのインスタンス化を担当しますが、実際には new...() 自体を呼び出さない場合があります - これは Java であるため、通常、最初に 1 つまたは 2 つのファクトリを通過します。
他の回答で提供されている概念図は役に立ちますが、役立つと思った別のポイントを共有したいと思います。
コード生成、ソース コード、またはリレーショナル データベースの DDL については、UML からいくらかのマイレージを取得しました。そこでは、コンポジションを使用して、テーブルが (データベース内の) null 非許容の外部キーと、null 非許容の「親」(および多くの場合「最終」) オブジェクトをコード内に持つことを示しました。レコードまたはオブジェクトが「孤立」として存在できる、親オブジェクトに関連付けられていない、または別の親オブジェクトによって「採用」されることを意図した集計を使用します。
言い換えれば、モデルのコードを書くときに必要になる可能性のある追加の制約を暗示するために、コンポジション表記を省略表現として使用しました。
条件を設定しましょう。Aggregation は UML 標準のメタ用語であり、構成と共有集計の両方を意味し、単純にsharedという名前です。多くの場合、誤って「集約」と呼ばれます。構成も集約であるため、これは悪いことです。私が理解しているように、あなたは「共有」を意味します。
さらにUML標準から:
複合 - プロパティが複合的に集約されることを示します。つまり、複合オブジェクトは、構成されたオブジェクト (パーツ) の存在と保管に責任を持ちます。
したがって、カテドラは大学の外には存在しないため、大学からカテドラスへの協会は構成です(私見)
共有集約の正確なセマンティクスは、アプリケーション領域とモデラーによって異なります。
つまり、他のすべてのアソシエーションは、自分または他の誰かのいくつかの原則に従っているだけであれば、共有された集合体として描くことができます。こちらもご覧ください。