関連付け、集約、構成の違いは何ですか?実装面で説明してください。
関連付け、集約、構成の違いは何ですか?実装面で説明してください。
回答:
二つのオブジェクトのために、Foo
とBar
の関係を定義することができます
関連付け -オブジェクトと関係があります。 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;
}
}
Bar
オブジェクトは存続する場合があります。
私はこの質問がC#としてタグ付けされていることを知っていますが、概念はこのリダイレクトのようなかなり一般的な質問です。そこで、ここに私の見解を示します(Javaの見方から少し偏っています)。
オブジェクト指向の性質について考えるとき、常にオブジェクト、クラス(オブジェクトの設計図)、およびそれらの間の関係について考えます。オブジェクトは関連しており、メソッドを介して互いに相互作用します。つまり、あるクラスのオブジェクトは、別のクラスのオブジェクトによって提供されるサービス/メソッドを使用できます。この種の関係は関連と呼ばれます。。
集約と構成は関連のサブセットであり、特定の関連ケースであることを意味します。
混乱していますか?
構成例:車とその車に非常に固有のエンジンの例を考えます(つまり、他の車では使用できません)。CarとSpecificEngineの間のこのタイプの関係クラスのは、コンポジションと呼ばれます。CarクラスのオブジェクトはSpecificEngineクラスのオブジェクトなしでは存在できず、SpecificEngineのオブジェクトはCarクラスなしでは意味がありません。簡単に言うと、CarクラスはSpecificEngineクラスのみを「所有」しています。
集計の例:ここで、CarクラスとWheelクラスを考えます。車が機能するにはWheelオブジェクトが必要です。CarオブジェクトがWheelオブジェクトを所有していることを意味しますが、CarオブジェクトがなければWheelオブジェクトに意味がないとは言えません。バイク、トラック、またはさまざまな車オブジェクトで使用できます。
まとめると-
まとめると、関連付けは、クラスが別のクラスによって提供される機能をいつ使用するかを表す非常に一般的な用語です。ある親クラスのオブジェクトが別の子クラスのオブジェクトを所有し、その子クラスのオブジェクトが親クラスのオブジェクトなしでは意味のある形で存在できない場合は、それを構成と言います。可能な場合は、集約と呼ばれます。
詳細はこちら。 私はhttp://opensourceforgeeks.blogspot.inの作成者であり、関連する投稿に上記のリンクを追加して、詳細を説明しています。
関連付けは、関係の一般化された概念です。これには、構成と集約の両方が含まれます。
合成(混合)は、単純なオブジェクトまたはデータ型を単一のユニットにラップする方法です。構成は、多くの基本的なデータ構造の重要な構成要素です
集約(コレクション)は、所有権を意味しないという点で通常の構成とは異なります。合成では、所有するオブジェクトが破壊されると、含まれるオブジェクトも破壊されます。集計では、これは必ずしも本当ではありません。
どちらもオブジェクト間の関係を示し、その強さのみが異なります。
違いを覚えるトリック:A - A集約とO wn-c O mpositoinがあります
次の画像を見てみましょう
類推:
構成:次の画像は画像の構成です。つまり、個々の画像を使用して1つの画像を作成しています。
集約:1つの場所にある画像のコレクション
たとえば、大学にはさまざまな学部があり、各学部には多数の教授がいます。大学が閉鎖されると、学部は存在しなくなりますが、それらの学部の教授は存続します。したがって、大学は学部の集まりと見なすことができますが、学部には教授の集合体があります。さらに、教授は複数の学部で働くことができますが、学部は複数の大学の一部であることはできません。
依存関係(参照)
これは、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();
}
}
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
};
他の人が言ったように、関連はオブジェクト間の関係であり、集約と合成は関連の一種です。
実装の観点から見ると、参照によってクラスメンバーを持つことで集計が得られます。たとえば、クラス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;
}
};
重要な点は、コンポジションではコンテナオブジェクトがコンテナオブジェクトを所有するのに対し、集約ではコンテナオブジェクトがそれを参照することです。
アソシエーション、アグリゲーション、コンポジションの 3つの関係概念の違いについてどれほど混乱があるかは驚くべきことです。
集約と構成という用語がC ++コミュニティで使用されていることに注意してください。おそらく、UMLクラス図で関連付けの特殊なケースとして定義される前のしばらくの間です。
主な問題は、構成の概念が全体とその部分の間のライフサイクル依存関係を意味し、全体がなければ部分が存在できないこと、さらには共有できないパーツとのパーツ全体の関連付けの場合、パーツは、パーツから切り離され、全体の破壊に耐えることができます。
私が見る限り、この混乱には2つのルーツがあります。
C ++コミュニティでは、「集約」という用語は、別の独立したクラスのオブジェクトを参照するための属性を定義するクラスの意味で使用されました(たとえば、[1]を参照)。これは、UMLクラス図における関連の意味です。「コンポジション」という用語は、オブジェクトのコンポーネントオブジェクトを定義するクラスに使用されました。そのため、複合オブジェクトの破棄時に、これらのコンポーネントオブジェクトも破棄されます。
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-関連付けまたは集約(単純なコードスニペット)
協会
関連付けは、2つのクラス間の関係を表します。単方向(一方向)または双方向(双方向)のいずれかになります。
例えば:
顧客が注文する
AはBと結婚している
BはAと結婚している
集計
集約は一種の関連ですが、特定の機能があります。集約は、1つの大きな「全体」クラスが1つ以上の小さな「パーツ」クラスを含む関係です。逆に、小さな「パーツ」クラスは「全体」の大きなクラスの一部です。
例えば:
クラブには会員がいます
クラブ(「全体」)は、複数のクラブメンバー(「部分」)で構成されます。メンバーは、クラブの外で生活することができます。クラブ(「全体」)が死ぬ場合、メンバー(「部分」)はそれで死ぬことはありません。会員は複数のクラブ(「全体」)に所属できるため。
組成
これは、より強力な集約形式です。「全体」は、「部分」の作成または破棄を担当します
例えば:
学校には学部があります
この場合、学校(「全体」)は死に、部門(「部分」)はそれと共に死ぬことになります。各パーツは1つの「全体」にのみ属することができるためです。
class Club(){ _member = new Member }
参照として使用 または渡す必要がありますclass Club(){ addMember(Member member) { this._member = member } }
関係線を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
class Person() { private hand = new Hand }
。睡眠集約人class Person() { private sleep = new Sleep }
は有効な睡眠で「新しい」キーを使用しますか?または集計なので、参照として渡す必要がありますか?class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }
構成(「全体」を削除すると、「部分」も自動的に削除されます–「所有権」)
新しいクラス内に既存のクラスのオブジェクトを作成します。新しいクラスは既存のクラスのオブジェクトで構成されるため、これはコンポジションと呼ばれます。
通常、通常のメンバー変数を使用します。
構成クラスがサブクラスの作成/破棄を担当する割り当て/割り当て解除を自動的に処理する場合、ポインター値を使用できます。
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 --------------------
これらの回答の問題は、それらが話の半分であるということです。彼らは、集約と構成は関連の形式であると説明していますが、関連がこれらのどちらでもない可能性があるかどうかは述べていません。
私は、SOに関する多くの投稿のいくつかの簡単な読みと、クラスの関連付けには4つの主要な具体的な形式があるといういくつかのUMLドキュメントに基づいて収集します。
2つのエンティティ間の関係がこれらのいずれでもない場合、それは単に用語の一般的な意味で「関連付け」と呼ぶことができ、さらに他の方法(メモ、ステレオタイプなど)を説明できます。
私の推測では、「一般的な関連付け」は主に次の2つの状況で使用されることを意図しています。
私はこのリンクがあなたの宿題をするだろうと思います:http : //ootips.org/uml-hasa.html
用語を理解するために、プログラミングの初期の頃の例を覚えています。
あなたは、「箱」のオブジェクトが含ま「チェスボード」オブジェクトがある場合は合成「チェス盤」が削除された場合のボックスはもう存在する理由はないために。
「カラー」オブジェクトを持つ「正方形」オブジェクトがあり、正方形が削除された場合、「カラー」オブジェクトがまだ存在している可能性があります。これは集約です。
どちらも関連付けです。主な違いは概念です
組成:これは、オブジェクト(学校)を破棄すると、それにバインドされている別のオブジェクト(教室)も破棄される場所です。どちらも独立して存在することはできません。
集約:これは、上記の(Composition
)関連付けの正反対であり、オブジェクト(Company
)を削除すると、それにEmployees
バインドされている他のオブジェクト()が単独で存在できるようになります。
協会。
構成と集約は、関連付けの2つの形式です。
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.
Railsで3つの用語がどのように実装されているかを説明したいと思います。ActiveRecordは、2つのモデル間のあらゆるタイプの関係をと呼びますassociation
。ドキュメントや記事を読んでいるときに、ActiveRecordに関連する用語composition
やを見つけることはあまりありませんaggregation
。関連は、関連クラスマクロの1つをクラスの本体に追加することによって作成されます。これらのマクロのいくつかはbelongs_to
、has_one
、has_many
など。
composition
またはを設定する場合は、所有モデル(子とも呼ばれる)または所有モデル(親とも呼ばれる)aggregation
に追加belongs_to
する必要があります。子モデルで呼び出しに渡すオプションを設定するか依存するか。Rails 5以前は、オプションなしで設定するとが作成され、子は親なしで存在できました。が必要な場合は、オプションを追加してこれを明示的に宣言する必要があります。has_one
has_many
composition
aggregation
belongs_to
belongs_to
aggregation
composition
required: 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
From:Remo H. Jansenの本「Beginning React:Learning TypeScript 2.x-Second Edition」:
協会と呼ぶオブジェクトの所有権がない独立したライフサイクルを持つオブジェクトを持つ関係を、ます。教師と生徒の例を見てみましょう。複数の生徒を1人の教師に関連付け、1人の生徒を複数の教師に関連付けることができますが、どちらも独立したライフサイクルを持っています(両方とも個別に作成および削除できます)。したがって、教師が学校を辞めるときに生徒を削除する必要はありません。また、生徒が学校を辞めるときに教師を削除する必要もありません。
集約と呼びますオブジェクトに独立したライフサイクルがあるが、所有権はあり、子オブジェクトは別の親オブジェクトに属することができない関係をます。携帯電話と携帯電話のバッテリーを例にとってみましょう。単一のバッテリーが電話に属している可能性がありますが、電話が機能を停止し、データベースから削除した場合、電話のバッテリーはまだ機能している可能性があるため削除されません。したがって、総称して、所有権はありますが、オブジェクトにはライフサイクルがあります
コンポジションという用語は、オブジェクトに独立したライフサイクルがない関係を指します。親オブジェクトが削除されると、すべての子オブジェクトも削除されます。質問と回答の関係の例を見てみましょう。単一の質問は複数の回答を持つことができ、回答は複数の質問に属することはできません。質問を削除すると、回答は自動的に削除されます。
アソシエーションは2つの個別のクラス間の関係であり、アソシエーションは1対1、1対5などの任意のタイプにすることができます。2つの完全に異なるエンティティを結合します。
アグリゲーションは、ウォレットクラスやマネークラスなど、クラス(またはエンティティ)間の単方向の一方向の関係である関連付けの特殊な形式です。ウォレットはお金を持っていますが、お金は必ずしもウォレットを持っている必要はないので、それは一方向の関係です。この関係では、他のエントリが終了しても、両方のエントリが存続できます。この例では、Walletクラスが存在しない場合でも、Moneyクラスが存在できないことを意味しません。
コンポジションは、2つのエンティティー(またはクラスと言えます)が相互に大きく依存している、集約の制限された形式です。たとえば、人間と心臓。人間は生きるために心を必要とし、心が生き残るためには人体を必要とします。言い換えると、クラス(エンティティ)が相互に依存していて、それらの寿命が同じである場合(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」タイプの関係になりますが、その逆は成り立ちません。