В чем разница между объединением, агрегацией и составом? Пожалуйста, объясните с точки зрения реализации.
В чем разница между объединением, агрегацией и составом? Пожалуйста, объясните с точки зрения реализации.
Ответы:
Для двух объектов 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 называется Composition. Объект класса Car не может существовать без объекта класса SpecificEngine, а объект класса SpecificEngine не имеет значения без класса Car. Проще говоря, класс Car является единственным владельцем класса SpecificEngine.
Пример агрегации : теперь рассмотрим класс Car и класс Wheel . Автомобиль нуждается в объекте Колесо, чтобы функционировать. То есть объект Car владеет объектом Wheel, но мы не можем сказать, что объект Wheel не имеет значения без объекта Car. Он может очень хорошо использоваться в Велосипеде, Грузовике или другом Объекте Автомобилей.
Подводя итог -
Подводя итог, можно сказать, что ассоциация - это очень общий термин, используемый для обозначения того, когда класс использует функции, предоставляемые другим классом. Мы говорим, что это композиция, если один объект родительского класса владеет другим объектом дочернего класса, и этот объект дочернего класса не может существенным образом существовать без объекта родительского класса. Если это возможно, то это называется Агрегация.
Подробнее здесь. Я являюсь автором http://opensourceforgeeks.blogspot.in и добавил ссылку выше на соответствующий пост для большего контекста.
Ассоциация является обобщенной концепцией отношений. Включает в себя как состав, так и агрегацию.
Композиция ( смесь ) - это способ объединить простые объекты или типы данных в одну единицу . Композиции являются важным строительным блоком многих базовых структур данных.
Агрегация ( сбор ) отличается от обычного состава тем, что не предполагает владения. В композиции, когда владелец объекта уничтожается, также и содержащиеся объекты. В совокупности это не обязательно верно.
Оба обозначают отношения между объектами и отличаются только их силой.
Trick помнить разницу: есть A - A ggregation и O WN - C O mpositoin
Теперь давайте посмотрим на следующее изображение
Аналогия:
Композиция : Следующая картинка представляет собой композицию изображения, т.е. использует отдельные изображения, составляющие одно изображение.
Агрегация : коллекция изображений в одном месте
Например, университет имеет различные факультеты, и на каждом факультете есть несколько профессоров. Если университет закроется, кафедры больше не будут существовать, но профессора на этих кафедрах продолжат существовать. Следовательно, университет можно рассматривать как состав кафедр, тогда как кафедры имеют совокупность профессоров. Кроме того, профессор может работать более чем на одном факультете, но факультет не может быть частью более чем одного университета.
Зависимость (ссылки)
Это означает, что между двумя объектами нет концептуальной связи. например, объект EnrollmentService ссылается на объекты Student и Course (как параметры метода или возвращаемые типы)
public class EnrollmentService {
public void enroll(Student s, Course c){}
}
Ассоциация (has-a)
Это означает, что почти всегда существует связь между объектами (они связаны). Объект заказа имеет объект Customer
public class Order {
private Customer customer
}
Агрегация (has-a + whole-part)
Специальный вид ассоциации, в которой существует отношение целых частей между двумя объектами. они могут жить друг без друга, хотя.
public class PlayList{
private List<Song> songs;
}
Примечание: самая сложная часть - отличить агрегацию от обычной ассоциации. Честно говоря, я думаю, что это открыто для разных интерпретаций.
Состав (has-a + целое-часть + владение)
Специальный вид агрегации. An Apartment
состоит из некоторых Room
s. А Room
не может существовать без Apartment
. при удалении квартиры удаляются также все связанные комнаты.
public class Apartment{
private Room bedroom;
public Apartment() {
bedroom = new Room();
}
}
Из поста Роберта Мартина в comp.object :
Ассоциация представляет способность одного экземпляра отправить сообщение другому экземпляру. Обычно это реализуется с помощью указателя или ссылочной переменной экземпляра, хотя это также может быть реализовано как аргумент метода или создание локальной переменной.
//[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;
}
};
Важным моментом является то, что в композиции контейнерному объекту принадлежит содержащийся в нем объект , а при агрегации он ссылается на него.
Удивительно, как много путаницы существует в отношении различия между тремя понятиями отношений: объединение , агрегация и состав. .
Обратите внимание, что термины агрегация и состав использовались в сообществе C ++, возможно, в течение некоторого времени, прежде чем они были определены как особые случаи ассоциации в диаграммах классов UML.
Основная проблема заключается в широко распространенном и постоянном недоразумении (даже среди опытных разработчиков программного обеспечения), что концепция композиции подразумевает зависимость жизненного цикла между целым и его частями, так что части не могут существовать без целого, игнорируя тот факт, что существуют также случаи ассоциаций части-целого с частями, не предназначенными для совместного использования, когда части можно отделить от целого и пережить его уничтожение.
Насколько я понимаю, эта путаница имеет два корня:
В сообществе C ++ термин «агрегация» использовался в смысле класса, определяющего атрибут для ссылки на объекты другого независимого класса (см., Например, [1]), что является смыслом ассоциации в диаграммах классов UML. Термин «композиция» использовался для классов, которые определяют объекты-компоненты для своих объектов, так что при уничтожении составного объекта эти объекты-компоненты также уничтожаются.
В диаграммах классов UML и «агрегация», и «композиция» были определены как особые случаи ассоциаций, представляющих отношения часть-целое (которые долгое время обсуждались в философии). В их определениях различие между «агрегацией» и «композицией» основано на том факте, позволяет ли оно разделять часть между двумя или более целыми. Они определяют «композиции» как имеющие не разделяемые (исключительные) части, в то время как «агрегаты» могут делиться своими частями. Кроме того, они говорят что-то вроде следующего: очень часто, но не во всех случаях, композиции имеют зависимость жизненного цикла между целым и его частями, так что части не могут существовать без целого.
Таким образом, хотя UML поместил термины «агрегация» и «композиция» в правильный контекст (отношения «часть-целое»), им не удалось дать им четкое и однозначное определение, охватывающее интуицию разработчиков. Тем не менее, это не удивительно, поскольку существует множество свойств (и нюансов реализации), которые могут иметь эти отношения, и разработчики не договариваются о том, как их реализовать.
Смотрите также мой расширенный ответ на вопрос SO от апреля 2009 года, указанный ниже.
И свойство, которое, как предполагалось, определяет «композицию» между объектами ООП в сообществе C ++ (и это убеждение все еще широко распространено): зависимость жизненного цикла во время выполнения между двумя связанными объектами (составной и ее компонент) не совсем характерно для «композиции», потому что мы можем иметь такие зависимости из-за ссылочной целостности и в других типах ассоциаций.
Например, следующий кодовый код для «композиции» был предложен в ответе 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 ]
Агрегация против Композиции [закрыто как основанная главным образом на мнении]
[ Апр 2009 ] В
чем разница между Композицией и Ассоциацией?
[ Май 2009 ]
Разница между объединением, агрегацией и составом
[ май 2009 ] В
чем разница между составом и агрегацией? [дубликаты]
[ октябрь 2009 г. ] В
чем разница между агрегацией, составом и зависимостью? [помечено как дубликат]
[ ноябрь 2010 ]
Ассоциация против агрегации [помечено как дубликат]
[Август 2012 ]
Разница в реализации между агрегацией и композицией в Java
[ февраль 2015 ]
UML - ассоциация или агрегация (простые фрагменты кода)
ассоциация
Ассоциация представляет отношения между двумя классами. Она может быть однонаправленной (односторонней) или двунаправленной (двухсторонней)
например:
Заказчик размещает заказы
А женат на Б
Б женат на А
агрегирование
Агрегация - это своего рода ассоциация. Но со специфическими особенностями. Агрегация - это отношение в одном большем «целом» классе, содержащем один или несколько меньших классов «частей». И наоборот, меньший класс «part» является частью «целого» более крупного класса ,
например:
в клубе есть члены
Клуб («целый») состоит из нескольких членов клуба («частей»). У члена есть жизнь вне клуба. Если бы клуб («целый») умер, члены («части») не умерли бы с ним. Потому что член может принадлежать нескольким клубам («целым»).
Сочинение
Это более сильная форма агрегации. «Целое» отвечает за создание или уничтожение своих «частей»
Например:
Школа имеет отделы
В этом случае школа («целое») должна была умереть, отдел («части») умрет с этим. Потому что каждая часть может принадлежать только одному «целому».
class Club(){ _member = new Member }
или передать его в качестве ссылкиclass Club(){ addMember(Member member) { this._member = member } }
Важно понять, почему мы должны беспокоиться об использовании более одного раза линии отношений. Наиболее очевидная причина заключается в описании отношений родитель-потомок между классами (когда родитель удалял все дочерние элементы удаляются в результате), но, что более важно, мы хотим различать простую ассоциацию и композицию, чтобы наложить неявные ограничения на видимость и распространение изменений в связанных классах, вопрос, который играет важную роль в понимании и уменьшении сложности системы.
ассоциация
Наиболее абстрактный способ описать статические отношения между классами - это использовать ссылку «Ассоциация», которая просто утверждает, что существует какая-то связь или зависимость между двумя классами или более.
Слабая Ассоциация
ClassA может быть связан с ClassB для того, чтобы показать, что один из его методов включает параметр экземпляра ClassB или возвращает экземпляр ClassB.
Сильная Ассоциация
ClassA также может быть связан с ClassB, чтобы показать, что он содержит ссылку на экземпляр ClassB.
Агрегация (Общая Ассоциация)
В тех случаях, когда между ClassA (целым) и ClassB (частичным) существует частичная связь, мы можем быть более конкретными и использовать ссылку агрегации вместо ссылки ассоциации, подчеркивая, что ClassB также может агрегироваться другими классами в приложении ( поэтому агрегация также называется общей ассоциацией).
Важно отметить, что ссылка агрегации никоим образом не говорит о том, что ClassA владеет ClassB, и что между ними есть родительско-дочерние отношения (когда родитель удалил все дочерние элементы, которые в результате удаляются). На самом деле, совсем наоборот! Ссылка агрегации обычно используется для подчеркивания того факта, что ClassA не является эксклюзивным контейнером ClassB, поскольку на самом деле ClassB имеет другой контейнер.
Агрегация против Ассоциации Ссылка ассоциации может заменить ссылку агрегации в любой ситуации, в то время как агрегация не может заменить ассоциацию в ситуациях, когда между классами есть только «слабая связь», то есть ClassA имеет методы, которые содержат параметр ClassB, а ClassA не хранить ссылку на экземпляр ClassB.
Мартин Фаулер предполагает, что ссылка агрегации вообще не должна использоваться, потому что она не имеет добавленной стоимости и нарушает согласованность, цитируя Джима Рамбо «Думайте об этом как о плацебо для моделирования».
Композиция (Не разделяемая ассоциация)
Мы должны быть более конкретными и использовать составную ссылку в тех случаях, когда в дополнение к частичной взаимосвязи между ClassA и ClassB - между ними существует сильная зависимость жизненного цикла, что означает, что когда 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 и некоторых документах UML, я понял, что существует 4 основных конкретных формы ассоциации классов:
Когда отношения между двумя объектами не являются одним из них, их можно просто назвать «ассоциацией» в общем смысле этого термина и далее описать другими способами (примечание, стереотип и т. Д.).
Я предполагаю, что «общая ассоциация» предназначена для использования в основном в двух обстоятельствах:
Я думаю, что эта ссылка сделает вашу домашнюю работу: http://ootips.org/uml-hasa.html
Чтобы понять термины, я помню пример в мои первые дни программирования:
Если у вас есть объект «шахматная доска», который содержит объекты «коробки», который является композицией потому что, если «шахматная доска» удалена, больше нет причин для существования блоков.
Если у вас есть «квадратный» объект, который имеет «цветной» объект, и квадрат удаляется, «цветной» объект все еще может существовать, то есть агрегация
Оба они являются ассоциациями , главное отличие - концептуальное.
Композиция : это когда вы уничтожаете объект (школу), другой объект (классные комнаты), который привязан к нему, тоже будет уничтожен. Оба они не могут существовать независимо.
Агрегация : Это своего рода полная противоположность Composition
ассоциации выше ( ), где, когда вы убиваете объект ( Company
), другой объект ( Employees
), связанный с ним, может существовать сам по себе.
Ассоциация .
Состав и агрегация - это две формы ассоциации.
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.
В очень простом предложении:
Агрегация и Композиция являются подмножествами ассоциации.
A использует B -> это агрегация
A нуждается B -> это композиция.
Узнайте больше здесь .
Я хотел бы проиллюстрировать, как три термина реализованы в Rails. ActiveRecord вызывает любой тип отношений между двумя моделями association
. Не нашел бы очень часто термины composition
и aggregation
, при чтении документации или статьи, связанные с ActiveRecord. Ассоциация создается путем добавления одного из макросов класса ассоциации в тело класса. Некоторые из этих макросов belongs_to
, has_one
и has_many
т. Д ..
Если мы хотим установить composition
или aggregation
, нам нужно добавить belongs_to
к собственной модели (также называемой дочерней) и has_one
или has_many
к модели-владельцу (также называемой родительской). Настроены ли мы composition
или aggregation
зависит от параметров, которые мы передаем belongs_to
вызову в дочерней модели. До Rails 5, установка 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
Из книги Ремо Х. Янсена «Начало реакции: изучение TypeScript 2.x - второе издание»:
Мы называем ассоциацию те отношения, чьи объекты имеют независимый жизненный цикл, в котором нет собственности на объекты. Давайте посмотрим на пример учителя и ученика. Несколько учеников могут быть связаны с одним учителем, а один ученик может быть связан с несколькими учителями, но оба имеют независимые жизненные циклы (оба могут создавать и удалять независимо). Поэтому, когда учитель покидает школу, нам не нужно удалять учеников, а когда ученик покидает школу, нам не нужно удалять учителей.
Мы называем агрегацию теми отношениями, чьи объекты имеют независимый жизненный цикл, но есть владение, и дочерние объекты не могут принадлежать другому родительскому объекту. Давайте рассмотрим пример сотового телефона и аккумулятора сотового телефона. Одна батарея может принадлежать телефону, но если телефон перестает работать, и мы удаляем его из нашей базы данных, батарея телефона не будет удалена, поскольку она все еще может функционировать. Таким образом, в совокупности, пока существует собственность, объекты имеют свой жизненный цикл
Мы используем термин состав для обозначения отношений, чьи объекты не имеют независимого жизненного цикла, и если родительский объект будет удален, все дочерние объекты также будут удалены. Давайте рассмотрим пример взаимосвязи между вопросами и ответами. Отдельные вопросы могут иметь несколько ответов, и ответы не могут принадлежать нескольким вопросам. Если мы удалим вопросы, ответы будут автоматически удалены.
ассоциация - это связь между двумя отдельными классами, и ассоциация может быть любого типа, скажем, один к одному, один к мая и т. Д. Она объединяет две совершенно разные сущности.
агрегирование - это особая форма ассоциации, которая представляет собой однонаправленные односторонние отношения между классами (или объектами), например, для классов Wallet и Money. У кошелька есть деньги, но деньги не обязательно должны быть у кошелька, так что это однонаправленные отношения. В этом отношении обе записи могут выжить, если другая заканчивается. В нашем примере, если класс Wallet отсутствует, это не означает, что класс Money не может существовать.
Композиция - это ограниченная форма агрегации, в которой две сущности (или, можно сказать, классы) сильно зависят друг от друга. Например, для человека и сердца. Человеку нужно сердце, чтобы жить, а сердцу нужно человеческое тело, чтобы выжить. Другими словами, когда классы (сущности) зависят друг от друга и их продолжительность жизни одинакова (если один умирает, то и другой тоже), тогда это композиция. Класс сердца не имеет смысла, если класса Человека нет.
https://www.linkedin.com/pulse/types-relationships-object-oriented-programming-oop-sarah-el-dawody/
Композиция: является частью отношений.
например, «двигатель - это часть автомобиля», «сердце - это часть тела».
Ассоциация: это отношение типа «есть»
Например, предположим, что у нас есть два класса, тогда эти два класса называются отношениями «имеет», если оба эти объекта совместно используют объект друг друга для некоторой работы, и в то же время они могут существовать без зависимости друг от друга или оба имеют свои собственная жизнь
Приведенный выше пример демонстрирует отношения ассоциации, поскольку класс Employee и Manager используют объект друг друга и оба имеют свой независимый жизненный цикл.
Агрегация: основана на отношениях "есть-а" и является специальной формой ассоциации
например, «Студент» и «адрес». У каждого учащегося должен быть адрес, поэтому отношения между классом ученика и классом адреса будут иметь тип отношения «Has-A», но наоборот это не так.