В чем разница между ассоциацией, агрегацией и составом?

В чем разница между ассоциацией, агрегацией и составом? Пожалуйста, объясните с точки зрения реализации.

  • Ассоциация – это отношения, в которых все объекты имеют свой жизненный цикл, и нет владельца.

    Возьмем пример Учителя и Студента. Несколько учеников могут общаться с одним учителем, а один студент может общаться с несколькими учителями, но нет никакого права собственности между объектами, и у обоих есть свой жизненный цикл. Оба могут быть созданы и удалены независимо.

  • Агрегация – это специализированная форма Ассоциации, где все объекты имеют собственный жизненный цикл, но собственность и дочерние объекты не могут принадлежать другому родительскому объекту.

    Давайте возьмем пример Департамента и учителя. Один преподаватель не может принадлежать нескольким отделам, но если мы удалим отдел, объект учителя не будет уничтожен. Мы можем думать об этом как об отношениях «есть-а».

  • Композиция снова является специализированной формой Агрегации, и мы можем назвать это как «смерть». Это сильный тип агрегирования. У дочернего объекта нет жизненного цикла, и если родительский объект удален, все дочерние объекты также будут удалены.

    Давайте снова возьмем пример отношений между Домом и Комнатами. Дом может содержать несколько комнат – нет независимой жизни комнаты, и любая комната не может принадлежать двум различным домам. Если мы удалим комнату, она автоматически будет удалена.

    Давайте рассмотрим еще один пример отношений между Вопросами и Опции. Отдельные вопросы могут иметь несколько опций, и опция не может принадлежать нескольким вопросам. Если мы удалим вопросы, параметры будут автоматически удалены.

Для двух объектов 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; } } 

Я знаю, что этот вопрос отмечен как C #, но концепции – это довольно общие вопросы, такие как redirect здесь. Поэтому я собираюсь предоставить свою точку зрения здесь (немного предвзято с точки зрения java, где мне удобнее).

Когда мы думаем об объектно-ориентированной природе, мы всегда думаем об объектах, classе (чертежах объектов) и о взаимосвязи между ними. Объекты связаны и взаимодействуют друг с другом с помощью методов. Другими словами, объект одного classа может использовать сервисы / методы, предоставляемые объектом другого classа. Такие отношения называются ассоциациями. ,

Агрегация и состав – это подмножества ассоциации, означающие, что они являются конкретными случаями ассоциации.

введите описание изображения здесь

  • В агрегированном и композиционном объекте одного classа «принадлежит» объект другого classа .
  • Но есть тонкая разница. В композиции объект classа, принадлежащий объекту принадлежащего ему classа, не может жить сам по себе (также называемый «отношения смерти»). Он всегда будет жить как часть принадлежащего ему объекта, где, как и в агрегировании, зависимый объект является автономным и может существовать, даже если объект владения classом мертв.
  • Таким образом, в составе, если владельцем объекта является garbage collection, принадлежащий ему объект также будет несовместим с агрегированием.

Смущенный?

Пример композиции : рассмотрите пример автомобиля и двигатель, который очень специфичен для этого автомобиля (что означает, что он не может использоваться в любом другом автомобиле). Этот тип отношения между classом Car и SpecificEngine называется Composition. Объект classа Car не может существовать без объекта SpecificEngine, а объект SpecificEngine не имеет значения без classа Car. Проще говоря, class Car исключительно «владеет» classом SpecificEngine.

Пример агрегирования : теперь рассмотрим class Car и class Wheel . Автомобилю нужен объект колеса для работы. Значение объекта объекта автомобиля для собственного колеса, но мы не можем сказать, что объект колеса не имеет значения без объекта автомобиля. Его вполне можно использовать в объекте Bike, Truck или Different Cars.

Подводя итог –

Подводя итог, ассоциация представляет собой очень общий термин, используемый для представления, когда на classе используются функции, предоставляемые другим classом. Мы говорим, что это композиция, если один объект родительского classа владеет другим объектом дочернего classа и этот объект дочернего classа не может иметь смысла без объекта родительского classа. Если это возможно, это называется агрегацией.

Подробнее здесь.

Ассоциация – это обобщенная концепция отношений. Он включает как состав, так и агрегацию.

Композиция ( смесь ) – это способ обернуть простые объекты или типы данных в один блок . Композиции являются критическим строительным блоком многих базовых структур данных

Агрегация ( сбор ) отличается от обычной композиции тем, что она не подразумевает права собственности. В композиции, когда объект-владелец уничтожается, также находятся объекты, содержащиеся в нем. В агрегации это не обязательно так.

Оба означают взаимосвязь между объектом и отличаются только своей силой.

введите описание изображения здесь

Теперь рассмотрим следующее изображение

связи

введите описание изображения здесь

Аналогия:

Состав : Следующий рисунок представляет собой композицию изображения, то есть используя отдельные изображения, делающие одно изображение.
введите описание изображения здесь

Агрегация : сбор изображения в одном месте

введите описание изображения здесь

Например, университет владеет различными отделами, и в каждом отделе есть несколько профессоров. Если университет закрывается, отделов больше не будет, но профессора в этих отделах будут продолжать существовать. Поэтому университет можно рассматривать как состав отделов, тогда как отделы имеют совокупность профессоров. Кроме того, профессор мог работать в нескольких отделениях, но отдел не мог быть частью более одного университета.

Из сообщения Роберта Мартина в comp.object :

Ассоциация представляет возможность одного экземпляра отправить сообщение другому экземпляру. Обычно это реализуется с переменной указателя или ссылочного экземпляра, хотя она также может быть реализована как аргумент метода или создание локальной переменной.

 //[Example:] //|A|----------->|B| class A { private: B* itsB; }; 

Агрегация […] – это типичная связь целое / часть. Это точно так же, как и ассоциация с исключением, что экземпляры не могут иметь циклические отношения агрегации (т.е. часть не может содержать все ее).

 //[Example:] //|Node|<>-------->|Node| class Node { private: vector itsNodes; }; 

Тот факт, что это агрегирование, означает, что экземпляры узла не могут сформировать цикл. Таким образом, это Дерево узлов, а не граф узлов.

Композиция […] точно такая же, как Агрегация, за исключением того, что время жизни «части» контролируется «целым». Этот контроль может быть прямым или транзитивным. То есть «целое» может взять на себя прямую ответственность за создание или уничтожение «части», или оно может принять уже созданную часть, а затем передать ее другому целому, которое берет на себя ответственность за это.

 //[Example:] //|Car|<#>-------->|Carburetor| class Car { public: virtual ~Car() {delete itsCarb;} private: Carburetor* itsCarb }; 

Зависимость (ссылки)
Это означает, что между двумя объектами нет концептуальной связи. например, объект объекта «Зачисление». Объекты Student & Course (как параметры метода или типы возврата)

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

Ассоциация (имеет-a)
Это означает, что почти всегда есть связь между объектами (они связаны). Объект Order имеет объект Customer

 public class Order { private Customer customer } 

Агрегация (имеет + целую часть)
Особый вид ассоциации, где существует целая связь между двумя объектами. они могли бы жить друг без друга.

 public class PlayList{ private List songs; } 

Примечание: самая сложная часть – отличить агрегацию от нормальной ассоциации. Честно говоря, я думаю, что это открыто для разных интерпретаций.

Состав (есть + целая часть + собственность)
Специальный вид агрегации. Apartment состоят из некоторых Room . Room не может существовать без Apartment . когда квартира удалена, все связанные комнаты также удаляются.

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

Как говорили другие, ассоциация – это взаимосвязь между объектами, агрегация и состав – это типы ассоциации.

С точки зрения реализации агрегирование получается с помощью элемента classа по ссылке . Например, если class А агрегирует объект classа B, у вас будет что-то вроде этого (в C ++):

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

Семантика агрегации заключается в том, что когда объект A уничтожается, объект B, который он хранит, все еще будет существовать. При использовании композиции у вас более сильные отношения, обычно путем хранения члена по значению :

 class A { B element; }; 

Здесь, когда объект A уничтожается, объект B, который он содержит, также будет уничтожен. Самый простой способ добиться этого – сохранить элемент по значению, но вы также можете использовать некоторый интеллектуальный указатель или удалить член в деструкторе:

 class A { std::auto_ptr element; }; class A { B * element; ~A() { delete B; } }; 

Важным моментом является то, что в композиции объект контейнера принадлежит содержащему его, тогда как в агрегации он ссылается на него.

Удивительно, насколько существует путаница в различии между тремя ассоциациями концепций, объединением и составом .

Обратите внимание, что агрегирование и состав терминов были использованы в сообществе C ++, вероятно, в течение некоторого времени, прежде чем они будут определены как особые случаи ассоциации в диаграммах classов UML.

Основная проблема заключается в распространенном и постоянном недоразумении (даже среди экспертов-разработчиков программного обеспечения), что концепция композиции подразумевает зависимость жизненного цикла между целым и его частями, так что части не могут существовать без целого, игнорируя тот факт, что существуют также случаи частичных объединений с неразделяемыми частями, где части могут быть отделены от и уничтожить целое.

Насколько я вижу, эта путаница имеет два корня:

  1. В сообществе C ++ термин «агрегация» использовался в смысле classа, определяющего атрибут для ссылки на объекты другого независимого classа (см., Например, [1]), что является смыслом ассоциации в диаграммах classов UML. Термин «композиция» использовался для classов, которые определяют объекты объектов для своих объектов, так что при уничтожении составного объекта эти объекты компонентов также уничтожаются.

  2. В диаграммах classов UML как «агрегация», так и «композиция» были определены как особые случаи ассоциаций, представляющих отношения частичного целого (которые долго обсуждались в философии). В своих определениях различие между «агрегацией» и «составом» основано на факте, если он позволяет разделять часть между двумя или более целыми. Они определяют «композиции» как имеющие неразделяемые (эксклюзивные) части, тогда как «агрегации» могут делиться своими частями. Кроме того, они говорят что-то вроде следующего: очень часто, но не во всех случаях, композиции имеют зависимость жизненного цикла между целым и его частями, так что части не могут существовать без целого.

Таким образом, в то время как UML поставил термины «агрегация» и «состав» в правильном контексте (отношений полного целого), им не удалось определить их четким и недвусмысленным образом, захватив интуицию разработчиков. Однако это не удивительно, потому что существует так много разных свойств (и нюансов реализации), которые могут иметь эти отношения, и разработчики не соглашаются с тем, как их реализовать.

См. Также мой расширенный ответ на вопрос SO в апреле 2009 года, приведенный ниже.

И свойство, которое предполагалось определить «состав» между объектами ООП в сообществе C ++ (и это мнение по-прежнему широко распространено): зависимость жизненного цикла между двумя связанными объектами (составной и его компонент) не очень характерны для «композиции», потому что мы можем иметь такие зависимости из-за ссылочной целостности и в других типах ассоциаций.

Например, в ответе SO была предложена следующая схема кода для «композиции»:

 final class Car { private final Engine engine; Car(EngineSpecs specs) { engine = new Engine(specs); } void move() { engine.work(); } } 

Респондент утверждал, что для «композиции» было бы характерно, что ни один другой class не мог ссылаться / знать компонент. Однако это, конечно, не верно для всех возможных случаев «композиции». В частности, в случае двигателя автомобиля изготовителю автомобиля, возможно, выполненному с помощью другого classа, возможно, придется ссылаться на двигатель, чтобы иметь возможность связаться с владельцем автомобиля, когда есть проблема с ним.

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

Приложение – Неполный список неоднократно задаваемых вопросов о составе по сравнению с агрегацией на StackOverflow

[ Апрель 2009 ]
Агрегация и композиция [закрыты, в основном, основанные на мнениях]
[ Апрель 2009 ]
В чем разница между композицией и ассоциацией? [ Май 2009 ]
Разница между ассоциацией, агрегацией и составом
[ Май 2009 ]
В чем разница между составом и агрегацией? [Дубликат]
[ Октябрь 2009 ]
В чем разница между агрегацией, составом и зависимостью? [отмечены как дубликаты]
[ Ноя 2010 ]
Ассоциация против агрегирования [отмечена как дубликат]
[ Август 2012 ]
Разница между агрегацией и композицией в Java
[ Февраль 2015 ]
UML – объединение или агрегация (простые fragmentы кода)

ассоциация

Ассоциация представляет собой взаимосвязь между двумя classами. Она может быть однонаправленной (в одну сторону) или двунаправленной (двухсторонней)

например:

  1. однонаправленный

Клиент размещает заказы

  1. двунаправленный

A женат на B

B женат на A

агрегирование

Агрегация – это своего рода ассоциация. Но с конкретными функциями. Агрегация – это отношение в одном более крупном classе «весь», содержит один или несколько меньших classов «частей». Обратно, меньший class «часть» является частью «целого» более крупного classа ,

например:

У клуба есть члены

Клуб («весь») состоит из нескольких членов клуба («части»). У члена есть жизнь вне клуба. Если клуб («целое») должен был умереть, члены («части») не умерли бы вместе с ним. Поскольку член может принадлежать нескольким клубам («целое»).

Состав

Это более сильная форма агрегации. «Целый» несет ответственность за создание или уничтожение своих «частей»,

Например:

В школе есть отделения

В этом случае школа («целая») должна была умереть, отдел («части») умрет вместе с ней. Потому что каждая часть может принадлежать только одному «целому».

Важно понять, почему мы должны даже беспокоиться о том, чтобы использовать линию отношений не один раз. Наиболее очевидной причиной является описание отношений между родителями и дочерними элементами между classами (когда родитель удалил все его дочерние элементы в результате), но более бессильно мы хотим различать простую ассоциацию и состав, чтобы помещать неявные ограничения на видимость и распространение изменений в связанных classах, вопрос, который играет важную роль в понимании и уменьшении сложности системы.

ассоциация

Самым абстрактным способом описания статической взаимосвязи между classами является ссылка ассоциации, которая просто утверждает, что существует какая-то связь или зависимость между двумя classами и более.

Слабая ассоциация

ClassA может быть связан с ClassB, чтобы показать, что один из его методов включает параметр экземпляра ClassB или возвращает экземпляр classа B.

Сильная ассоциация

ClassA также может быть связан с ClassB, чтобы показать, что он содержит ссылку на экземпляр ClassB.

Агрегация (Объединенная ассоциация)

В тех случаях, когда есть часть отношений между ClassA (целое) и ClassB (часть), мы можем быть более конкретными и использовать ссылку агрегирования вместо ссылки ассоциации, подчеркивая, что ClassB также может быть агрегирован другими classами в приложении ( поэтому агрегация также известна как совместная ассоциация).

введите описание изображения здесь

Важно отметить, что ссылка на агрегирование никак не заявляет, что ClassA принадлежит ClassB или что отношения между родителями и дочерними элементами (когда родитель удалил все его дочерние элементы в результате) между ними. Собственно, все наоборот! Ссылка на агрегирование обычно используется, чтобы подчеркнуть, что ClassA не является эксклюзивным контейнером ClassB, поскольку на самом деле ClassB имеет другой контейнер.

Агрегация против Ассоциации . Ссылка ассоциации может заменить ссылку агрегации в каждой ситуации, в то время как агрегация не может заменить связь в ситуациях, когда между classами существует только «слабая связь», то есть ClassA имеет метод / s, который содержит параметр ClassB, но ClassA не удерживайте ссылку на экземпляр ClassB.

Мартин Фаулер предполагает, что ссылка на агрегацию не должна использоваться вообще, потому что она не имеет добавленной стоимости и не нарушает согласованности, цитируя Джима Рэмбо «Думайте об этом как о плацебо моделирования».

Композиция (не разделяемая ассоциация)

Мы должны быть более конкретными и использовать компоновку ссылок в тех случаях, когда в дополнение к частичной зависимости между ClassA и ClassB существует сильная зависимость жизненного цикла между ними, а это означает, что когда ClassA удаляется, тогда ClassB также удаляется

введите описание изображения здесь

Ссылка на композицию показывает, что class (контейнер, целое) имеет исключительное право владения над другим classом / частями (частями), что означает, что объект-контейнер и его части являются отношением parent-child / s.

В отличие от ассоциации и агрегации, при использовании отношения композиции составной class не может отображаться как тип возврата или тип параметра составного classа. Таким образом, изменения составленного classа не могут распространяться на остальную часть системы. Следовательно, использование композиции ограничивает рост сложности по мере роста системы.

Сложность измерительной системы

Системную сложность можно измерить просто, посмотрев диаграмму classов UML и оценив линии связи ассоциации, агрегации и состава. Способ измерения сложности – определить, на сколько classов может повлиять изменение определенного classа. Если class A предоставляет class B, то на любой class, который использует class A, теоретически могут влиять изменения в classе B. Сумма числа потенциально затронутых classов для каждого classа в системе – общая сложность системы.

Вы можете прочитать здесь: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html


Связь между двумя объектами называется ассоциацией .

Ассоциация известна как композиция, когда один объект владеет другим.

Хотя ассоциация известна как агрегация, когда один объект использует другой объект.

Проблема с этими ответами заключается в том, что они – половина истории: они объясняют, что агрегация и состав – это формы ассоциации, но они не говорят, что объединение может быть ни тем, ни другим.

Я собираюсь основать на некоторых кратких чтениях многих сообщений о SO и некоторых документах UML, что есть четыре основные конкретные формы ассоциации classов:

  1. композиция: A составлена ​​из B; B не существует без A, как комната в доме
  2. агрегация: A имеет-a B; B может существовать без A, как ученик в classе
  3. зависимость: A использует-a B; нет зависимости от жизненного цикла между A и B, например, параметра вызова метода, возвращаемого значения или временного, созданного во время вызова метода
  4. обобщение: A is-a B

Когда связь между двумя объектами не является одной из них, ее можно просто называть «ассоциацией» в общем смысле этого слова и далее описывать другие способы (примечание, стереотип и т. Д.).

Я предполагаю, что «общая ассоциация» предназначена для использования в основном в двух обстоятельствах:

  • когда специфика отношений все еще разрабатывается; такая связь на диаграмме должна быть как можно скорее преобразована в то, что она на самом деле есть / будет (одна из остальных 4).
  • когда отношение не соответствует ни одному из этих 4, предопределенных UML; «общая» ассоциация по-прежнему дает вам способ представления отношений, которые «не являются одними из других», так что вы не застреваете, используя неправильную связь с запиской «это на самом деле не агрегация, а просто UML не имеет другого символа, который мы могли бы использовать ”

Я думаю, что эта ссылка сделает домашнее задание: http://ootips.org/uml-hasa.html

Чтобы понять термины, которые я помню, пример в мои ранние дни программирования:

Если у вас есть объект «шахматной доски», который содержит «полевые» объекты, которые являются композицией, потому что, если «шахматная доска» удалена, нет никаких оснований для того, чтобы ящики существовали больше.

Если у вас есть «квадратный» объект с «цветным» объектом и квадрат удаляется, объект «color» может все еще существовать, это агрегирование

Оба они являются ассоциациями , основное отличие – концептуальное

Композиция : Это когда вы уничтожаете объект (Школа), другой объект (classные комнаты), который связан с ним, также будет уничтожен. Оба они не могут существовать независимо.

Агрегация : это как раз противоположная вышеприведенная ( Composition ) ассоциация, где, когда вы убиваете объект ( Company ), другой объект ( Employees ), который связан с ним, может существовать сам по себе.

Ассоциации .
Состав и агрегация являются двумя формами ассоциации.

Состав (Если вы удалите «целое», «часть» также автоматически удаляется – «Собственность»)

  • Создайте объекты своего существующего classа внутри нового classа. Это называется композицией, потому что новый class состоит из объектов существующих classов.

  • Обычно используют обычные переменные-члены.

  • Может использовать значения указателя, если class композиции автоматически обрабатывает распределение / освобождение, ответственное за создание / уничтожение подclassов.

введите описание изображения здесь

Композиция в C ++

 #include  using namespace std; /********************** Engine Class ******************/ class Engine { int nEngineNumber; public: Engine(int nEngineNo); ~Engine(void); }; Engine::Engine(int nEngineNo) { cout<<" Engine :: Constructor " < 

Вывод

 --------------- 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 -------------------- 

Агрегация (Если вы удалите «целое», «Часть» может существовать - «Без права собственности»)

  • Агрегация - это особый тип композиции, где не подразумевается владение между сложным объектом и подобъектами. Когда агрегат уничтожается, подобъекты не уничтожаются.

  • Обычно используют переменные указателя / ссылочную переменную, указывающие на объект, который живет за пределами classа агрегата

  • Может использовать ссылочные значения, указывающие на объект, который живет вне области совокупного classа

  • Не отвечает за создание / уничтожение подclassов

введите описание изображения здесь

Агрегационный код в C ++

 #include  #include  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 :: "< 

Вывод

 --------------- 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 -------------------- 

Я хотел бы проиллюстрировать, как три условия реализованы в Rails. ActiveRecord вызывает любой тип отношений между двумя моделями. При чтении документации или статей, связанных с ActiveRecord, очень часто не приходилось составлять composition и aggregation терминов. Связь создается добавлением одного из макросов classа ассоциации в тело classа. Некоторые из этих макросов принадлежат 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 опцию 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 
Давайте будем гением компьютера.