関連付け、集約、構成の違いは何ですか?


389

関連付け、集約、構成の違いは何ですか?実装面で説明してください。


2
これは初心者には少々圧倒されるかもしれませんが、UML 2スーパーストラクチャー仕様を少し散歩してください:omg.org/docs/formal/09-02-02.pdf 協会のセクション7.3.3
チキンナビスケット2009年

6
また、UML 2には集約や構成などの要素はありません(ただし、UML 1.4にはありました)。UML 2では、集約/構成は、AggregationKindプロパティがSharedまたはCompositeに設定されたAssociation要素として実装されます。
chickeninabiscuit

SOに関するたくさんの回答:stackoverflow.com/search
q

2
ここで有用な製品codeproject.com/Articles/22769/...
GibboK

6
私はこれがすでに何度も回答されていることを知っていますが、この問題について今まで読んだ中で最も良い説明はこれだと思います:holub.com/goodies/uml/#composition
WLin

回答:


385

二つのオブジェクトのために、FooBarの関係を定義することができます

関連付け -オブジェクトと関係があります。 Foo使用するBar

public class Foo { 
    void Baz(Bar bar) {
    } 
};

構成 -私はオブジェクトを所有しており、その存続期間について責任があります。ときFooダイが、そうBar

public class Foo {
    private Bar bar = new Bar(); 
}

集計 -他の人から借りたオブジェクトがあります。Foo死ぬとき、Bar生き続けるかもしれません。

public class Foo { 
    private Bar bar; 
    Foo(Bar bar) { 
       this.bar = bar; 
    }
}

3
C#/ Javaコードのようです。その場合、関連コードと集計コードは同じです。どちらの場合も、 'bar'は参照されるだけで、Barオブジェクトは存続する場合があります。
アジェイ2014

@ジェフフォスター:私はいくつかの疑問があります。Baz(Bar bar){bar = new Bar();でバーオブジェクトをインスタンス化する場合 最初のケースでは}。それはまだ協会なのか、それとも今作曲になるのか?
Saket 2014

21
@Ajay:アグリゲーションはオブジェクトの参照を保持しますが、関連付けの場合はそうではありません。したがって、実装の違い。
ABCD

17
関連付けは、メソッドパラメータとしての単なる使用よりも少し強力です。あなたのアソシエーションコードスニペットはDependencyリレーションに対応していると思います。Martin Fowlerに関する記事
Ahmad Abdelghany

5
@AhmadAbdelghanyは正しいです。最初の例は依存関係です。3つ目は、関連付けと集約のために機能します。
アンドレ・ヴァレンティ

122

私はこの質問がC#としてタグ付けされていることを知っていますが、概念はこのリダイレクトのようなかなり一般的な質問です。そこで、ここに私の見解を示します(Javaの見方から少し偏っています)。

オブジェクト指向の性質について考えるとき、常にオブジェクト、クラス(オブジェクトの設計図)、およびそれらの間の関係について考えます。オブジェクトは関連しており、メソッドを介して互いに相互作用します。つまり、あるクラスのオブジェクトは、別のクラスのオブジェクトによって提供されるサービス/メソッドを使用できます。この種の関係は関連と呼ばれます。

集約と構成は関連のサブセットであり、特定の関連ケースであることを意味します。

ここに画像の説明を入力してください

  • あるクラスの集約オブジェクトと構成オブジェクトの両方で、別のクラスの「所有」オブジェクト
  • しかし、微妙な違いがあります。で構成そのオブジェクトが所有するクラスのオブジェクトは、クラスを所有しています、それ自身でライブすることはできません(また、「死の関係」と呼ばれます)。それは常にその所有オブジェクトの一部として存在しますが、Aggregationの場合と同様に、依存オブジェクトはスタンドアロンであり、所有クラスのオブジェクトが無効であっても存在できます。
  • したがって、合成では、所有オブジェクトがガベージコレクションの場合、所有オブジェクトも集約されますが、そうではありません。

混乱していますか?

構成例:車とその車に非常に固有のエンジンの例を考えます(つまり、他の車では使用できません)。CarSpecificEngineの間のこのタイプの関係クラスのは、コンポジションと呼ばれます。CarクラスのオブジェクトはSpecificEngineクラスのオブジェクトなしでは存在できず、SpecificEngineのオブジェクトはCarクラスなしでは意味がありません。簡単に言うと、CarクラスはSpecificEngineクラスのみを「所有」しています。

集計の例:ここで、CarクラスとWheelクラスを考えます。車が機能するにはWheelオブジェクトが必要です。CarオブジェクトがWheelオブジェクトを所有していることを意味しますが、CarオブジェクトがなければWheelオブジェクトに意味がないとは言えません。バイク、トラック、またはさまざまな車オブジェクトで使用できます。

まとめると-

まとめると、関連付けは、クラスが別のクラスによって提供される機能をいつ使用するかを表す非常に一般的な用語です。ある親クラスのオブジェクトが別の子クラスのオブジェクトを所有し、その子クラスのオブジェクトが親クラスのオブジェクトなしでは意味のある形で存在できない場合は、それを構成と言います。可能な場合は、集約と呼ばれます。

詳細はこちら。 私はhttp://opensourceforgeeks.blogspot.inの作成者であり、関連する投稿に上記のリンクを追加して、詳細を説明しています。


8
5年以上前に尋ねられた既に回答済みの質問にどうして答えるのか気になった理由を尋ねようとしましたが、それからあなたのブログエントリを読みました。賛成です!
Donbhupi

2
私は@Donbhupiに同意します。あなたの答えは他の多くの情報よりもはるかに有益で正確です
zish

1
C#とJavaの開発者が、それらの言語のプリミティブ型にのみ存在する場合にコンポジションを使用すると主張するのは、本当に面白いです。あなたが本当に構図を理解したい場合は、C ++オブジェクトが実際に他のオブジェクトの一部であることができる場所だけで、ヒープメモリに浮かぶ、お互いへのポインタを保持して主張していない..構図がある。..使用する必要があります
みんな

@私はあなたと同じ結論に達した全員ですが、私はそれを確信していません。たとえば、ある特定のクラスによって意味的に所有されているクラスが1つありますが、所有されているオブジェクトは、その所有者がガベージコレクターによって既に削除された後にガベージコレクションされますが、コンポジションと見なされますか?
パウロ・アンドレHaacke

管理されたメモリを使用して、c#コード内で構成できますか?
PauloAndréHaacke

85

関連付けは、関係の一般化された概念です。これには、構成と集約の両方が含まれます。

合成混合)は、単純なオブジェクトまたはデータ型を単一のユニットにラップする方法です。構成は、多くの基本的なデータ構造の重要な構成要素です

集約コレクション)は、所有権を意味しないという点で通常の構成とは異なります。合成では、所有するオブジェクトが破壊されると、含まれるオブジェクトも破壊されます。集計では、これは必ずしも本当ではありません。

どちらもオブジェクト間の関係を示し、その強さのみが異なります。

違いを覚えるトリック:A - A集約とO wn-c O mpositoinがあります

ここに画像の説明を入力してください

次の画像を見てみましょう

関係

ここに画像の説明を入力してください

類推:

構成:次の画像は画像の構成です。つまり、個々の画像を使用して1つの画像を作成しています。
ここに画像の説明を入力してください

集約:1つの場所にある画像のコレクション

ここに画像の説明を入力してください

たとえば、大学にはさまざまな学部があり、各学部には多数の教授がいます。大学が閉鎖されると、学部は存在しなくなりますが、それらの学部の教授は存続します。したがって、大学は学部の集まりと見なすことができますが、学部には教授の集合体があります。さらに、教授は複数の学部で働くことができますが、学部は複数の大学の一部であることはできません。


14
このトピックについてよく読んだ後、この答えは最も直感的に理解できるものです。ウィキペディアに置く必要があります。
Jankapunkt 2017

1
美しく表現されています。
シド

集約に関しては、「子オブジェクトは単一の親に属している」と言います。これは正しくありません。集計を共有することは有効なUMLです。つまり、子は複数の親に属しています。教授については、教授の集合体としての例でこれを認めています。教授は複数の部門で働くことができるからです。
www.admiraalit.nl

@ www.admiraalit.nl AFAIK共有集約は、「子が複数の親に属している」という意味ではありません。逆に言えば、複数の子が同じ親に属しています。そして、親が死んだとしても、子供はより長く生き残るかもしれないので、それは非複合集約です。
aderchox

65

依存関係(参照)
これは、2つのオブジェクト間に概念的なリンクがないことを意味します。例:EnrollmentServiceオブジェクトは、(メソッドパラメータまたは戻り値の型として)StudentおよびCourseオブジェクトを参照します。

public class EnrollmentService {
    public void enroll(Student s, Course c){}
}

協会(持っている- )
これは、オブジェクト間のリンクは、(それらが関連している)ほとんど常に存在することを意味します。Orderオブジェクトには Customerオブジェクトがあります

public class Order {
    private Customer customer
}

集約(has-a +全体)
2つのオブジェクト間に全体関係がある特別な種類の関連付け。彼らはお互いなしで生きるかもしれません。

public class PlayList{
    private List<Song> songs;
}

注:最もトリッキーな部分は、集計と通常の関連付けを区別することです。正直なところ、これはさまざまな解釈に受け入れられると思います。

構成(has-a +全体+所有権)
特別な種類の集約。AnがApartmentいくつかで構成されているRoomの。はRoom、なしでは存在できませんApartment。アパートが削除されると、関連するすべての部屋も削除されます。

public class Apartment{
    private Room bedroom;
    public Apartment() {
       bedroom = new Room();
    }
}

1
うん、オブジェクトの関係を決定する際の唯一のトリッキーな部分は、関連と集約を区別することです。他はすべて明確です。私からの+1
Fouad Boukredine

28

comp.objectのRobert Martinによる投稿から:

関連付けは、あるインスタンスが別のインスタンスにメッセージを送信する機能を表します。これは通常、ポインターまたは参照インスタンス変数を使用して実装されますが、メソッド引数として実装されたり、ローカル変数の作成として実装されたりする場合もあります。

//[Example:]

//|A|----------->|B|

class A
{
  private:
    B* itsB;
};

集約[...]は、典型的な全体/部分の関係です。これは、インスタンスが循環集約関係を持つことができない(つまり、部分が全体を含むことができない)ことを除いて、関連付けとまったく同じです。

//[Example:]

//|Node|<>-------->|Node|

class Node
{
  private:
    vector<Node*> itsNodes;
};

これが集約であるという事実は、Nodeのインスタンスが循環を形成できないことを意味します。したがって、これはノードのグラフではなく、ノードのツリーです。

構成[...]は、「パーツ」のライフタイムが「全体」によって制御されることを除いて、集約とまったく同じです。このコントロールは、直接または推移的です。つまり、「全体」が「パーツ」の作成または破棄に直接責任を負うか、またはすでに作成されたパーツを受け入れて、後でそれを担当する他の全体に渡す場合があります。

//[Example:]

//|Car|<#>-------->|Carburetor|

class Car
{
  public:
    virtual ~Car() {delete itsCarb;}
  private:
    Carburetor* itsCarb
};

1
この定義にはどの程度の権限がありますか?UML標準の作成者によってサポートされていますか?ツールでサポートされていますか?
reinierpost 2012年

1
ロバート・C・マーティンです。それは私にとって十分な権限です:-)
ヘリアック

21

他の人が言ったように、関連はオブジェクト間の関係であり、集約と合成は関連の一種です。

実装の観点から見ると、参照によってクラスメンバーを持つことで集計が得られます。たとえば、クラスAがクラスBのオブジェクトを集約すると、次のようなものになります(C ++の場合)。

class A {
    B & element;
  // or B * element;
};

集約のセマンティクスは、オブジェクトAが破棄されても、それが格納しているBオブジェクトがまだ存在することです。構成を使用する場合、通常はメンバーを値で格納することにより、より強い関係が得られます

class A {
    B element;
};

ここで、Aオブジェクトが破棄されると、それに含まれるBオブジェクトも破棄されます。これを行う最も簡単な方法は、メンバーを値で格納することですが、スマートポインターを使用したり、デストラクタでメンバーを削除したりすることもできます。

class A {
    std::auto_ptr<B> element;
};

class A {
    B * element;

    ~A() {
        delete B;
    }
};

重要な点は、コンポジションではコンテナオブジェクトコンテナオブジェクトを所有するのに対し、集約ではコンテナオブジェクトそれを参照することです。


8
これが唯一の受け入れられる答えであるべきです。プリミティブ型を除いて、C#およびJavaにはコンポジションは存在しません...しかし、それらの言語の開発者はコンポジションを「説明」しています。合成とは、オブジェクトが別のオブジェクトの中に存在することを意味します。JavaとC#では、それを行うことさえできません。すべてがヒープ上にあり、ポインタを保持するだけです。これは、実際には構成ではなく集計です。C ++ ..組成物を提供する
みんな

14

アソシエーションアグリゲーションコンポジションの 3つの関係概念の違いについてどれほど混乱があるかは驚くべきことです。

集約構成という用語がC ++コミュニティで使用されていることに注意してください。おそらく、UMLクラス図で関連付けの特殊なケースとして定義される前のしばらくの間です。

主な問題は、構成の概念が全体とその部分の間のライフサイクル依存関係を意味し、全体がなければ部分が存在できないこと、さらには共有できないパーツとのパーツ全体の関連付けの場合、パーツは、パーツから切り離され、全体の破壊に耐えることができます。

私が見る限り、この混乱には2つのルーツがあります。

  1. C ++コミュニティでは、「集約」という用語は、別の独立したクラスのオブジェクトを参照するための属性を定義するクラスの意味で使用されました(たとえば、[1]を参照)。これは、UMLクラス図における関連の意味です。「コンポジション」という用語は、オブジェクトのコンポーネントオブジェクトを定義するクラスに使用されました。そのため、複合オブジェクトの破棄時に、これらのコンポーネントオブジェクトも破棄されます。

  2. UMLクラス図では、「集約」と「合成」の両方が、部分と全体の関係を表す関連付けの特別なケースとして定義されています(これは長い間哲学で議論されてきました)。それらの定義では、「集約」と「構成」の区別は、2つ以上の全体で一部を共有できるかどうかという事実に基づいています。それらは、「構成」が共有できない(排他的な)部分を持っていると定義し、「集合体」はそれらの部分を共有する場合があります。加えて、彼らは次のようなことを言っています:非常に頻繁に、しかしすべてではないが、コンポジションは全体とその部分の間にライフサイクル依存関係を持ち、全体がなければその部分は存在できません。

したがって、UMLは「集約」および「構成」という用語を(部分全体の関係の)正しいコンテキストに置いていますが、明確かつ明確な方法でそれらを定義することはできず、開発者の直感を捉えています。ただし、これらの関係にはさまざまなプロパティ(および実装のニュアンス)があり、開発者はそれらの実装方法に同意していないため、これは当然のことです。

下記の2009年4月のSO質問に対する私の拡張回答も参照してください。

そして、C ++コミュニティのOOPオブジェクト間の「構成」を定義すると想定されたプロパティ(そしてこの信念はまだ広く保持されています):2つの関連オブジェクト(コンポジットとそのコンポーネント)間のランタイムライフサイクル依存関係は、他のタイプのアソシエーションでも参照整合性が原因でこのような依存関係が発生する可能性があるため、「コンポジション」にはそれほど特徴的ではありません。

たとえば、「構成」の次のコードパターンは、SOの回答で提案されています

final class Car {    
  private final Engine engine;

  Car(EngineSpecs specs) {
    engine = new Engine(specs);
  }

  void move() {
    engine.work();
  }
}

回答者は、他のクラスがコンポーネントを参照/認識できないことが「構成」に特徴的であると主張しました。ただし、これが「作曲」のすべての可能なケースに当てはまるわけではありません。特に、車のエンジンの場合、別のクラスの助けを借りて実装された可能性のある車のメーカーは、問題がある場合はいつでも車の所有者に連絡できるように、エンジンを参照する必要があります。

[1] http://www.learncpp.com/cpp-tutorial/103-aggregation/

付録-StackOverflowでの構成と集約について繰り返し尋ねられる質問の不完全なリスト

[ 2009年4月 ]
集計と構成 [主に意見に基づいて終了]
[ 2009年4月 ]
構成と関連の関係の違いは何ですか?
[ 2009年5月 ]
関連付け、集計、構成の違い
[ 2009年5月 ]
構成と集計の違いは何ですか。[重複]
[ 2009年10月 ]
集約、構成、依存関係の違いは何ですか?[重複としてマーク]
[ 2010年11月 ]
アソシエーションvsアグリゲーション [重複としてマーク] [2012年8月 ]

Javaでの集約と合成の実装の違い
[ 2015年2月 ]
UML-関連付けまたは集約(単純なコードスニペット)


繰り返し尋ねられる質問の不完全なリストに賛成票を投じてください。
ジャッコ、

13

協会

関連付けは、2つのクラス間の関係を表します。単方向(一方向)または双方向(双方向)のいずれかになります。

例えば:

  1. 一方向

顧客が注文する

  1. 双方向の

AはBと結婚している

BはAと結婚している

集計

集約は一種の関連ですが、特定の機能があります。集約は、1つの大きな「全体」クラスが1つ以上の小さな「パーツ」クラスを含む関係です。逆に、小さな「パーツ」クラスは「全体」の大きなクラスの一部です。

例えば:

クラブには会員がいます

クラブ(「全体」)は、複数のクラブメンバー(「部分」)で構成されます。メンバーは、クラブの外で生活することができます。クラブ(「全体」)が死ぬ場合、メンバー(「部分」)はそれで死ぬことはありません。会員は複数のクラブ(「全体」)に所属できるため。

組成

これは、より強力な集約形式です。「全体」は、「部分」の作成または破棄を担当します

例えば:

学校には学部があります

この場合、学校(「全体」)は死に、部門(「部分」)はそれと共に死ぬことになります。各パーツは1つの「全体」にのみ属することができるためです。


集約の場合。class Club(){ _member = new Member } 参照として使用 または渡す必要がありますclass Club(){ addMember(Member member) { this._member = member } }
ロール

12

関係線を2回以上使用することに煩わしい理由を理解することが重要です。最も明白な理由は、クラス間の親子関係を記述することです(親がそのすべての子を削除すると、結果として削除されます)が、より簡単に、単純な関連付けと構成を区別して、可視性と関連するクラスへの変更の伝播、システムの複雑さの理解と軽減に重要な役割を果たす問題。

協会

クラス間の静的な関係を記述する最も抽象的な方法は、Associationリンクを使用することです。これは単に、2種類以上のクラス間に何らかのリンクまたは依存関係があることを示しています。

弱い協会

ClassAをClassBにリンクして、そのメソッドの1つにClassBインスタンスのパラメーターが含まれているか、ClassBのインスタンスが返されることを示すことができます。

強い協会

ClassAは、ClassBインスタンスへの参照を保持していることを示すために、ClassBにリンクすることもできます。

集約(共有協会)

ClassA(全体)とClassB(部分)の一部の関係がある場合は、より具体的にして、関連付けリンクの代わりに集約リンクを使用して、ClassBがアプリケーションの他のクラスによっても集約できることを強調します(したがって、集約は共有関連付けとも呼ばれます)。

ここに画像の説明を入力してください

集約リンクには、ClassAがClassBを所有していることや、親子関係(親がその子をすべて削除したときに結果としてすべての子が削除されている)があることは一切記載されていないことに注意することが重要です。実際、まったく逆です!実際、ClassBには別のコンテナがあるので、ClassAがClassBの排他的なコンテナではないという点を強調するために通常使用される集約リンク。

集計と関連付け アソシエーションリンクは、あらゆる状況でアグリゲーションリンクを置き換えることができますが、アグリゲーションは、クラス間に「弱いリンク」しかない場合、つまりClassAにClassBのパラメーターを含むメソッドがあり、ClassAがそうでない状況ではアソシエーションを置き換えることができません。 ClassBインスタンスへの参照を保持します。

Martin Fowlerは、付加価値がなく、一貫性を損なうため、集約リンクはまったく使用すべきではないと示唆しています。JimRumbaughは「モデリングプラセボとして考える」と述べています。

構成(非共有協会)

ClassAとClassBのpart-of関係に加えて、2つの間に強いライフサイクル依存関係がある場合、より具体的に構成リンクを使用する必要があります。つまり、ClassAが削除されると、結果としてClassBも削除されます。

ここに画像の説明を入力してください

構成リンクは、クラス(コンテナ、全体)が他のクラス(パーツ)よりも排他的な所有権を持っていることを示します。つまり、コンテナオブジェクトとそのパーツが親子関係を構成します。

関連付けや集計とは異なり、構成関係を使用する場合、構成されたクラスは、複合クラスの戻り値型またはパラメーター型として表示できません。したがって、構成されたクラスへの変更は、システムの残りの部分に伝播できません。その結果、システムの成長に伴い、コンポジションの使用により複雑さの成長が制限されます。

システムの複雑さの測定

システムの複雑さは、UMLクラス図を見て、関連、集約、構成の関係線を評価するだけで測定できます。複雑さを測定する方法は、特定のクラスを変更することによって影響を受ける可能性があるクラスの数を決定することです。クラスAがクラスBを公開する場合、クラスAを使用する特定のクラスは、理論的にはクラスBへの変更によって影響を受ける可能性があります。システム内のすべてのクラスの潜在的に影響を受けるクラスの数の合計は、システム全体の複雑さです。

あなたは私のブログでもっと読むことができます:http//aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html



いい答えです。1)構成例の質問:Leng and Hand(composition)Person。私がクラス「動物」と「睡眠」を作成すると、睡眠(集合)人物になります。睡眠(集合)動物。それが正しいか?2)。手の構成人:class Person() { private hand = new Hand }。睡眠集約人class Person() { private sleep = new Sleep }は有効な睡眠で「新しい」キーを使用しますか?または集計なので、参照として渡す必要がありますか?class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }
ロール

7

構成(「全体」を削除すると、「部分」も自動的に削除されます–「所有権」)

  • 新しいクラス内に既存のクラスのオブジェクトを作成します。新しいクラスは既存のクラスのオブジェクトで構成されるため、これはコンポジションと呼ばれます。

  • 通常、通常のメンバー変数を使用します。

  • 構成クラスがサブクラスの作成/破棄を担当する割り当て/割り当て解除を自動的に処理する場合、ポインター値を使用できます。

ここに画像の説明を入力してください

C ++での構成

#include <iostream>
using namespace std;
/********************** Engine Class ******************/
class Engine
{
    int nEngineNumber;
    public:
    Engine(int nEngineNo);
    ~Engine(void);
};
Engine::Engine(int nEngineNo)
{
    cout<<" Engine :: Constructor " <<endl;
}
Engine::~Engine(void)
{
    cout<<" Engine :: Destructor " <<endl;
}
/********************** Car Class ******************/
class Car
{
    int nCarColorNumber;
    int nCarModelNumber;
    Engine objEngine;
    public:
    Car (int, int,int);
    ~Car(void);
};
Car::Car(int nModelNo,int nColorNo, int nEngineNo):
nCarModelNumber(nModelNo),nCarColorNumber(nColorNo),objEngine(nEngineNo)
{
    cout<<" Car :: Constructor " <<endl;
}
Car::~Car(void)
{
    cout<<" Car :: Destructor " <<endl;
    Car
    Engine
    Figure 1 : Composition
}
/********************** Bus Class ******************/
class Bus
{
    int nBusColorNumber;
    int nBusModelNumber;
    Engine* ptrEngine;
    public:
    Bus(int,int,int);
    ~Bus(void);
};
Bus::Bus(int nModelNo,int nColorNo, int nEngineNo):
nBusModelNumber(nModelNo),nBusColorNumber(nColorNo)
{
    ptrEngine = new Engine(nEngineNo);
    cout<<" Bus :: Constructor " <<endl;
}
Bus::~Bus(void)
{
    cout<<" Bus :: Destructor " <<endl;
    delete ptrEngine;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    // Composition using simple Engine in a car object
    {
        cout<<"------------- Inside Car Block ------------------"<<endl;
        Car objCar (1, 2,3);
    }
    cout<<"------------- Out of Car Block ------------------"<<endl;
    // Composition using pointer of Engine in a Bus object
    {
        cout<<"------------- Inside Bus Block ------------------"<<endl;
        Bus objBus(11, 22,33);
    }
    cout<<"------------- Out of Bus Block ------------------"<<endl;
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

出力

--------------- Start Of Program --------------------
------------- Inside Car Block ------------------
Engine :: Constructor
Car :: Constructor
Car :: Destructor
Engine :: Destructor
------------- Out of Car Block ------------------
------------- Inside Bus Block ------------------
Engine :: Constructor
Bus :: Constructor
Bus :: Destructor
Engine :: Destructor
------------- Out of Bus Block ------------------
--------------- End Of Program --------------------

集約(「全体」を削除すると、「一部」が存在する可能性があります–「所有権なし」)

  • 集約は、複合オブジェクトとサブオブジェクト間の所有権が暗示されない特定のタイプの構成です。集合体が破棄されても、サブオブジェクトは破棄されません。

  • 通常、集約クラスのスコープ外にあるオブジェクトを指すポインター変数/参照変数を使用します

  • 集約クラスのスコープ外にあるオブジェクトを指す参照値を使用できます

  • サブクラスの作成/破棄は担当していません

ここに画像の説明を入力してください

C ++の集計コード

#include <iostream>
#include <string>
using namespace std;
/********************** Teacher Class ******************/
class Teacher
{
    private:
    string m_strName;
    public:
    Teacher(string strName);
    ~Teacher(void);
    string GetName();
};
Teacher::Teacher(string strName) : m_strName(strName)
{
    cout<<" Teacher :: Constructor --- Teacher Name :: "<<m_strName<<endl;
}
Teacher::~Teacher(void)
{
    cout<<" Teacher :: Destructor --- Teacher Name :: "<<m_strName<<endl;
}
string Teacher::GetName()
{
    return m_strName;
}
/********************** Department Class ******************/
class Department
{
    private:
    Teacher *m_pcTeacher;
    Teacher& m_refTeacher;
    public:
    Department(Teacher *pcTeacher, Teacher& objTeacher);
    ~Department(void);
};
Department::Department(Teacher *pcTeacher, Teacher& objTeacher)
: m_pcTeacher(pcTeacher), m_refTeacher(objTeacher)
{
    cout<<" Department :: Constructor " <<endl;
}
Department::~Department(void)
{
    cout<<" Department :: Destructor " <<endl;
}
/********************** Main Function ******************/
int main()
{
    freopen ("InstallationDump.Log", "w", stdout);
    cout<<"--------------- Start Of Program --------------------"<<endl;
    {
        // Create a teacher outside the scope of the Department
        Teacher objTeacher("Reference Teacher");
        Teacher *pTeacher = new Teacher("Pointer Teacher"); // create a teacher
        {
            cout<<"------------- Inside Block ------------------"<<endl;
            // Create a department and use the constructor parameter to pass the teacher to it.
            Department cDept(pTeacher,objTeacher);
            Department
            Teacher
            Figure 2: Aggregation
        } // cDept goes out of scope here and is destroyed
        cout<<"------------- Out of Block ------------------"<<endl;
        // pTeacher still exists here because cDept did not destroy it
        delete pTeacher;
    }
    cout<<"--------------- End Of Program --------------------"<<endl;
    fclose (stdout);
}

出力

--------------- Start Of Program --------------------
Teacher :: Constructor --- Teacher Name :: Reference Teacher
Teacher :: Constructor --- Teacher Name :: Pointer Teacher
------------- Inside Block ------------------
Department :: Constructor
Department :: Destructor
------------- Out of Block ------------------
Teacher :: Destructor --- Teacher Name :: Pointer Teacher
Teacher :: Destructor --- Teacher Name :: Reference Teacher
--------------- End Of Program --------------------

この回答に反対票を投じた人。反対投票の理由を説明していただけますか?
Saurabh Raoot 2018年

私を本当に混乱させるのは、多くの場合、それは所有者が物を保持するのではなく、それが所有する物が所有者を「保持する」ということです。たとえば、車にはEngine *型のポインターはありませんが、Engineクラスには、それを所有する車を格納するCar型のメンバーがあります。特に、この場合のクラスのUML関係はよくわかりません。
dudu 2018

6

これらの回答の問題は、それらが話の半分であるということです。彼らは、集約と構成は関連の形式であると説明していますが、関連がこれらのどちらでもない可能性があるかどうかは述べていません。

私は、SOに関する多くの投稿のいくつかの簡単な読みと、クラスの関連付けには4つの主要な具体的な形式があるといういくつかのUMLドキュメントに基づいて収集します。

  1. 構成:AはBで構成されています。家の部屋のように、BはAなしでは存在しません
  2. 集約:AはBを持っています。教室の学生のように、BはAなしで存在できます
  3. 依存関係:AはBを使用します。メソッド呼び出しパラメーター、戻り値、またはメソッド呼び出し中に作成された一時的なものなど、AとBの間にライフサイクルの依存関係がない
  4. 汎化:A is-a B

2つのエンティティ間の関係がこれらのいずれでもない場合、それは単に用語の一般的な意味で「関連付け」と呼ぶことができ、さらに他の方法(メモ、ステレオタイプなど)を説明できます。

私の推測では、「一般的な関連付け」は主に次の2つの状況で使用されることを意図しています。

  • 関係の詳細がまだ解決されていないとき; ダイアグラムのこのような関係は、できるだけ早く実際のものに変換する必要があります(他の4つのうちの1つ)。
  • 関係がUMLによって事前に決定された4つのいずれとも一致しない場合。「一般的な」関連付けは、「他の関係ではない」関係を表す方法を提供するため、「これは実際には集約ではなく、単にUMLである」という注記を付けた誤った関係を使用して立ち往生することはありません。使用できる他の記号はありません」

1
他のすべてのオプションが除外された場合、どの程度正確に一般的な関連付けを実装しますか?AがBで構成されていない場合(Bの値はAにある)、AはBの集約ではない(Bの参照はAにない)、BはAから継承/実現されておらず、Bは戻り値、パラメーター、または内部で使用されていないAの関数の使用法については、ほとんど何の関係もありません。
Dean P

1
@DeanPとりあえず一般的なものにすることができ、後で4つのいずれかに変換されます(実装可能になります)。または、「似ている」ことを意味する関連付けが必要であると言うように、4に適合しない関係である可能性があります。一般的な関連付けがないと、4のいずれかを使用せざるを得なくなり、読者を誤解させます。一般的には、注釈を付けるか、それが何であるかを説明するメモを付けます。ほとんどの人は、記号を理解していない場合にのみメモを読みます;)
Oliver

5

私はこのリンクがあなたの宿題をするだろうと思います:http : //ootips.org/uml-hasa.html

用語を理解するために、プログラミングの初期の頃の例を覚えています。

あなたは、「箱」のオブジェクトが含ま「チェスボード」オブジェクトがある場合は合成「チェス盤」が削除された場合のボックスはもう存在する理由はないために。

「カラー」オブジェクトを持つ「正方形」オブジェクトがあり、正方形が削除された場合、「カラー」オブジェクトがまだ存在している可能性があります。これは集約です。

どちらも関連付けです。主な違いは概念です


5

組成:これは、オブジェクト(学校)を破棄すると、それにバインドされている別のオブジェクト(教室)も破棄される場所です。どちらも独立して存在することはできません。

集約:これは、上記の(Composition)関連付けの正反対であり、オブジェクト(Company)を削除すると、それにEmployeesバインドされている他のオブジェクト()が単独で存在できるようになります。

協会
構成と集約は、関連付けの2つの形式です。


1
厳密に言えば、会社の従業員は会社なしでは存在できません。確かに、あなたは人々を殺さないが、彼らはもはやその会社の従業員ではない。ですから、支店と従業員のほうが似ていると思います。支店が閉鎖されても、彼らは引き続き会社の従業員である可能性があります。
アレクサンダー

1
うん、絶対に。同意してください... +1指摘してくれてありがとう@AlexPopov。:)
クラサンガー

4
    Simple rules:
    A "owns" B = Composition : B has no meaning or purpose in the system 
    without A
    A "uses" B = Aggregation : B exists independently (conceptually) from A
    A "belongs/Have" B= Association; And B exists just have a relation
    Example 1:

    A Company is an aggregation of Employees.
    A Company is a composition of Accounts. When a Company ceases to do 
    business its Accounts cease to exist but its People continue to exist. 
    Employees have association relationship with each other.

    Example 2: (very simplified)
    A Text Editor owns a Buffer (composition). A Text Editor uses a File 
    (aggregation). When the Text Editor is closed,
    the Buffer is destroyed but the File itself is not destroyed.


2

Railsで3つの用語がどのように実装されているかを説明したいと思います。ActiveRecordは、2つのモデル間のあらゆるタイプの関係をと呼びますassociation。ドキュメントや記事を読んでいるときに、ActiveRecordに関連する用語compositionやを見つけることはあまりありませんaggregation。関連は、関連クラスマクロの1つをクラスの本体に追加することによって作成されます。これらのマクロのいくつかはbelongs_tohas_onehas_manyなど。

compositionまたはを設定する場合は、所有モデル(子とも呼ばれる)または所有モデル(親とも呼ばれる)aggregationに追加belongs_toする必要があります。子モデルで呼び出しに渡すオプションを設定するか依存するか。Rails 5以前は、オプションなしで設定するとが作成され、子は親なしで存在できました。が必要な場合は、オプションを追加してこれを明示的に宣言する必要があります。has_onehas_manycompositionaggregationbelongs_tobelongs_toaggregationcompositionrequired: true

class Room < ActiveRecord::Base
  belongs_to :house, required: true
end

Rails 5ではこれが変更されました。現在、belongs_to関連付けを宣言するとcompositionデフォルトでが作成され、親がなければ子は存在できません。したがって、上記の例は次のように書き直すことができます。

class Room < ApplicationRecord
  belongs_to :house
end

親なしで子オブジェクトが存在できるようにする場合は、オプションを使用してこれを明示的に宣言する必要があります optional

class Product < ApplicationRecord
  belongs_to :category, optional: true
end

2

From:Remo H. Jansenの本「Beginning React:Learning TypeScript 2.x-Second Edition」:

協会と呼ぶオブジェクトの所有権がない独立したライフサイクルを持つオブジェクトを持つ関係を、ます。教師と生徒の例を見てみましょう。複数の生徒を1人の教師に関連付け、1人の生徒を複数の教師に関連付けることができますが、どちらも独立したライフサイクルを持っています(両方とも個別に作成および削除できます)。したがって、教師が学校を辞めるときに生徒を削除する必要はありません。また、生徒が学校を辞めるときに教師を削除する必要もありません。

集約と呼びますオブジェクトに独立したライフサイクルがあるが、所有権はあり、子オブジェクトは別の親オブジェクトに属することができない関係をます。携帯電話と携帯電話のバッテリーを例にとってみましょう。単一のバッテリーが電話に属している可能性がありますが、電話が機能を停止し、データベースから削除した場合、電話のバッテリーはまだ機能している可能性があるため削除されません。したがって、総称して、所有権はありますが、オブジェクトにはライフサイクルがあります

コンポジションという用語は、オブジェクトに独立したライフサイクルがない関係を指します。親オブジェクトが削除されると、すべての子オブジェクトも削除されます。質問と回答の関係の例を見てみましょう。単一の質問は複数の回答を持つことができ、回答は複数の質問に属することはできません。質問を削除すると、回答は自動的に削除されます。


1

アソシエーションは2つの個別のクラス間の関係であり、アソシエーションは1対1、1対5などの任意のタイプにすることができます。2つの完全に異なるエンティティを結合します。

アグリゲーションは、ウォレットクラスやマネークラスなど、クラス(またはエンティティ)間の単方向の一方向の関係である関連付けの特殊な形式です。ウォレットはお金を持っていますが、お金は必ずしもウォレットを持っている必要はないので、それは一方向の関係です。この関係では、他のエントリが終了しても、両方のエントリが存続できます。この例では、Walletクラスが存在しない場合でも、Moneyクラスが存在できないことを意味しません。

コンポジションは、2つのエンティティー(またはクラスと言えます)が相互に大きく依存している、集約の制限された形式です。たとえば、人間と心臓。人間は生きるために心を必要とし、心が生き残るためには人体を必要とします。言い換えると、クラス(エンティティ)が相互に依存していて、それらの寿命が同じである場合(1つが死亡し、もう1つも死亡する場合)、その構成です。人間クラスが存在しない場合、ハートクラスは意味がありません。


1

https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/

構成:「一部」の関係です。

たとえば、「エンジンは車の一部」、「心臓は体の一部」などです。

ここに画像の説明を入力してください

協会:「has-a」タイプの関係です

たとえば、2つのクラスがあるとします。これらの2つのクラスは、両方のエンティティが作業のために互いのオブジェクトを共有し、同時にそれらが互いの依存関係なしで存在できるか、または両方にそれらがある場合、「has-a」関係と呼ばれます。自分の寿命。

ここに画像の説明を入力してください

上記の例は、相互のオブジェクトを使用するEmployeeクラスとManagerクラスの両方、および独自の独立したライフサイクルによる関連付け関係を示しています。

集約:「has-a」関係に基づいており、それが\\ aの特別な形式の関連付けです

たとえば、「学生」や「住所」などです。各学生は住所を持っている必要があるため、学生クラスと住所クラスの関係は「Has-A」タイプの関係になりますが、その逆は成り立ちません。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.