Агрегація проти складу [закрито]


90

Мені було важко зрозуміти різницю між складом та агрегацією в UML. Чи може хтось запропонувати мені гарне порівняння та протиставлення між ними? Я також хотів би навчитися розпізнавати різницю між ними в коді та / або бачити короткий приклад програмного забезпечення / коду.

Редагувати: Частина причин, чому я запитую, полягає в зворотному документообігу, який ми робимо на роботі. Ми написали код, але нам потрібно повернутися назад і створити схеми класів для коду. Ми просто хотіли б правильно зафіксувати асоціації.


Також див.
Розбіжність

Будь ласка, перевірте приклад на основі коду за адресою: stackoverflow.com/questions/731802/…
Almir Campos

UML 2.5 пояснив різницю. Дивіться рамку на стор. 110. Тож я голосую за те, щоб знову відкрити це.
qwerty_so

Ні, UML 2.5 не пояснив визначення композиції, навпаки, він залишався неоднозначним щодо цього, оскільки вони також говорять: "Об'єкт частини може бути видалений із складеного об'єкта до того, як складений об'єкт буде видалений, і, отже, не буде видалений як частина складений об'єкт ". Дивіться мою відповідь нижче ( stackoverflow.com/questions/734891/… ), де я намагався з’ясувати значення композиції. Будь ласка, проголосуйте мою відповідь, щоб показати, що в результаті SO правильна відповідь перемагає в підсумку :-) [або проти всіх неправильних відповідей]
Герд Вагнер,

Відповіді:


91

Різниця між агрегацією та складом залежить від контексту.

Візьмемо приклад автомобіля, згаданий в іншій відповіді - так, це правда, що вихлопна система автомобіля може стояти "сама по собі", тому може бути не у складі машини - але це залежить від програми. Якщо ви створите додаток, яке насправді має справу з автономними вихлопами автомобілів (програма управління автомагазином?), Агрегація буде вашим вибором. Але якщо це проста гоночна гра, і вихлопні гази автомобіля служать лише частиною машини - ну, склад буде цілком чудовим.

Шахова дошка? Та сама проблема. Шахова фігура не існує без шахової дошки лише в певних програмах. В інших (як у виробника іграшок) шахова фігура, безумовно, не може бути складена в шахову дошку.

Справа стає ще гіршою, коли ви намагаєтеся зіставити композицію / агрегацію з вашою улюбленою мовою програмування. У деяких мовах різницю можна легше помітити ("за посиланням" проти "за значенням", коли все просто), але в інших може взагалі не існувати.

І останнє слово поради? Не витрачайте занадто багато часу на це питання. Не варто. Різниця навряд чи корисна на практиці (навіть якщо у вас є повністю чіткий "склад", ви все одно можете застосувати його як агрегування з технічних причин - наприклад, кешування).


1
Я сказав шаховий квадрат, а не фігурка, але всі діючі бали.
Девід М

2
Я однозначно сприймаю думку "Не варто". Якщо ви не продумаєте, хто "володіє" об'єктом і відповідає за його тривалість життя, ви отримаєте дуже гадкий код, пов'язаний з CRUD об'єкта, зокрема очищення, з нульовими вказівниками, які летять, оскільки ієрархії об'єктів перебувають у поганому стані.
Кріс Кессель,

9
Так, вам не слід витрачати надто багато часу на це питання: UML - це мова OOA / OOD; Агрегація / склад зазвичай є рішенням, яке найкраще відкласти до ООП. Якщо ви намагаєтеся докласти занадто багато деталей до своїх моделей UML, ви ризикуєте паралізувати аналіз.
шимпанзе

13
+1 за "не витрачайте на це занадто багато часу". Це те, що мені потрібно було почути!
Ронні,

8
"не витрачайте на це занадто багато часу" Чому інтерв'юери цього не розуміють?
titogeo

97

Як правило: введіть тут опис зображення

class Person {
    private Heart heart;
    private List<Hand> hands;
}

class City {
    private List<Tree> trees;
    private List<Car> cars
}

У композиції (Людина, Серце, Рука) «під об’єкти» (Серце, Рука) будуть знищені, як тільки Людина буде знищена.

У сукупності (Місто, Дерево, Автомобіль) "під об'єкти" (Дерево, Автомобіль) НЕ будуть знищені, коли Місто буде знищено.

Суть в тому, що склад наголошує на взаємному існуванні, і в сукупності ця властивість НЕ потрібна.


2
взаємне існування, хороший B-)
jxramos

Цінуйте ваші зусилля. Дуже гарне пояснення, і будь-який неспеціаліст може це зрозуміти.
Равіндран Каннія

Найпростіше та найкраще пояснення, з яким я стикався.
Акаш Рагав,

найкраще пояснення :)
Сябілі

UML 2.5 пояснив різницю. Дивіться рамку на стор. 110. Отже, ваша відповідь просто неправильна зараз,
qwerty_so

51

Склад та агрегація - типи асоціацій. Вони дуже тісно пов’язані, і з точки зору програмування, здається, немає великої різниці між ними. Я спробую пояснити різницю між цими двома прикладами коду Java

Агрегація : Об'єкт існує поза іншим, створюється зовні, тому передається як аргумент (наприклад) конструктору. Напр .: Люди - машина. Автомобіль створюється в іншому контексті, а потім стає власністю людини.

// code example for Aggregation:
// reference existing HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer(HttpListener listener, RequestProcessor processor) {
    this.listener = listener;
    this.processor = processor;
  }
}

Склад : Об’єкт існує лише або має сенс лише всередині іншого, як частина іншого. Напр .: Люди - серце. Ви не створюєте серця, а потім передаєте його людині. Натомість серце створюється тоді, коли створюється людина.

// code example for composition:
// create own HttpListener and RequestProcessor
public class WebServer {
  private HttpListener listener;
  private RequestProcessor processor;
  public WebServer() {
    this.listener = new HttpListener(80);
    this.processor = new RequestProcessor(“/www/root”);
  }
}

Пояснено тут на прикладі Різниця між агрегацією та складом


5
Одна з найкращих відповідей на сьогодні. Охайний :)
Рохіт Сінгх

6
Найкращий приклад коду Java показує, коли об’єкт може існувати з (складом) чи без (об’єднання) іншими об’єктами.
Міхал Добі Добжанський,

будь ласка, я хочу знати, чи слід нам використовувати final для Composition чи ні?
Outreagous ONE

36

Композиція означає, що дочірні предмети мають спільний термін життя з батьками. Агрегація ні. Наприклад, шахова дошка складається з шахових квадратів - шахові квадрати насправді не існують без дошки. Однак автомобіль - це сукупність деталей - вихлопна система автомобіля все ще є вихлопною системою автомобіля, якщо на той момент вона не є частиною автомобіля.


18

Прикладом, який я дізнався, були пальці на руці. Ваша рука складається з пальців. Воно їм належить. Якщо рука гине, пальці гинуть. Не можна «агрегувати» пальці. Ви не можете просто захопити зайві пальці і прикріпити та від’єднати їх від руки за бажанням.

З точки зору дизайну, значення тут часто пов’язане з тривалістю життя об’єкта, як сказав інший плакат. Скажімо, у вас є Клієнт, а вони мають Рахунок. Цей рахунок є "складеним" об'єктом клієнта (принаймні, в більшості контекстів, які я можу придумати). Якщо ви видалите Клієнта, Обліковий запис не має жодної цінності, тому він буде також видалений. Зворотне часто буває при створенні об’єкта. Оскільки Обліковий запис має значення лише в контексті Клієнта, Ви повинні створити Обліковий запис як частину створення Клієнта (або, якщо Ви робите це ліниво, це буде частиною якоїсь транзакції Клієнта).

У дизайні корисно думати про те, які об’єкти володіють (складають) інші об’єкти, порівняно з тими, які просто посилаються (об’єднують) інші об’єкти. Це може допомогти визначити, де лежить відповідальність за створення / очищення / оновлення об’єктів.

Що стосується коду, часто важко сказати. Більшість коду в коді є посиланням на об’єкт, тому може бути не очевидно, чи об’єкт, на який посилається, складається (належить) чи агрегується.


15

Дивно , як багато плутанини існує розбіжності між частину-ціле - об'єднання понять агрегації і композиції . Основною проблемою є поширене непорозуміння (навіть серед експертів-розробників програмного забезпечення та серед авторів UML), що поняття композиції передбачає залежність життєвого циклу між цілим та його частинами, так що частини не можуть існувати без цілого. Але ця точка зору ігнорує той факт, що існують також випадки часткових цілих асоціацій з нерозподіленими частинами, де ці частини можна від'єднати від цілого і пережити його руйнування.

У документі специфікації UML визначення поняття "композиція" завжди передбачало нерозмінні частини, але не було ясно, що є визначальною характеристикою "композиції", а що є просто необов'язковою характеристикою. Навіть у новій версії (станом на 2015 рік), UML 2.5, після спроби вдосконалити визначення поняття "склад", він все ще залишається неоднозначним і не містить жодних вказівок щодо моделювання частково-цілих асоціацій з не- спільні частини, де частини можна від’єднати від цілого і пережити його знищення, на відміну від випадку, коли частини неможливо від’єднати і знищуються разом із цілим. Вони кажуть

Якщо складений об’єкт видаляється, усі його екземпляри частин, які є об’єктами, видаляються разом із ним.

Але в той же час вони також говорять

Об'єкт-частина може бути видалений із складеного об'єкта до того, як складений об'єкт буде видалений, і, отже, не буде видалений як частина складеного об'єкта.

Ця плутанина вказує на неповноту визначення UML, яке не враховує залежності життєвого циклу між компонентами та композитами. Тому важливо зрозуміти, як можна вдосконалити визначення UML, запровадивши стереотип UML для << нерозривних >> композицій, де компоненти неможливо від'єднати від їх композиту, і, отже, їх потрібно знищувати щоразу, коли їх композит руйнується.

1) Склад

Як пояснив Мартін Фаулер , головне питання, що характеризує композицію, полягає в тому, що "об'єкт може бути лише частиною одного композиційного зв'язку". Це також пояснюється у чудовому дописі в блозі UML Composition vs Aggregation vs Association від Geert Bellekens. На додаток до цієї визначальної характеристики композиції (щоб мати ексклюзивні або нерозподіляються частини), композиція може також мати залежність життєвого циклу між композитом та його компонентами. Насправді існує два види таких залежностей:

  1. Кожного разу, коли компонент завжди повинен бути приєднаний до композиту, або, іншими словами, коли він має обов’язковий композит , що виражається кратністю "рівно одна" на складовій стороні композиційної лінії, тоді він повинен бути використаний повторно в (або знову прикріплений до) іншого композиту або знищений, коли його нинішній композит знищений Прикладом цього є склад між Personі Heart, показаний на діаграмі нижче. Серце або знищується, або пересаджується іншій людині, коли його власник помер.
  2. Коли компонент не може бути від'єднаний від композиту, або, іншими словами, коли він невіддільний , тоді і лише тоді компонент повинен бути знищений, коли його композит зруйнований. Прикладом такої композиції з нероздільними частинами є композиція між Personі Brain.

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

Підсумовуючи, залежності життєвого циклу стосуються лише конкретних випадків складу, але не в цілому, тому вони не є визначальною характеристикою.

У специфікації UML зазначено: "Частина може бути видалена зі складеного екземпляра перед тим, як складений екземпляр буде видалений, і, отже, не може бути видалена як частина складеного екземпляра." У прикладі a Car- Engineкомпозиції, як показано на наступній схемі, очевидно, що двигун можна від'єднати від автомобіля до того, як автомобіль буде зруйнований, і в цьому випадку двигун не руйнується і може бути використаний повторно. Це передбачається нульовою або однією кратністю на складеній стороні композиційної лінії.

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

Кратність кінця асоціації композиції , по меншій композиційної стороні дорівнює 1 або 0..1, в залежності від того , якщо компоненти мають обов'язковий композит (повинно бути приєднані до складеного) чи ні. Якщо компоненти нероздільні , це означає, що вони мають обов’язковий композит.

2) Агрегація

Агрегація - це ще одна особлива форма асоціації із передбачуваним значенням відносини частина ціле, коли частини цілого можуть ділитися з іншими цілими. Наприклад, ми можемо змоделювати агрегування між класами, DegreeProgramі Course, як показано на наступній схемі, оскільки курс є частиною дипломної програми, і курс може бути спільним для двох або більше дипломних програм (наприклад, інженерний ступінь може поділяти C курс програмування зі ступенем інформатики).

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

Однак концепція агрегації з частинами, що діляться, насправді не означає багато, тому вона не має жодних наслідків для реалізації, тому багато розробників вважають за краще не використовувати білий діамант у своїх діаграмах класів, а просто моделюють просту асоціацію натомість. У специфікації UML сказано: "Точна семантика спільного агрегування залежить від області застосування та моделятора".

Кратність кінця асоціації агрегації по крайней всій стороні може бути будь-яке число (*) , так як частина може належати або спільно серед, будь-якої кількості цілісності.


2
Композиція не суворо пов’язана з життєвим циклом, але в більшості реальних світових проблем життєвий цикл є головним мотиватором того, чи складати ви, чи складати. У своїй відповіді я підстрахувався, сказавши, що життєвий цикл "часто" пов'язаний, а не завжди пов'язаний. Приємно зауважити, що життєвий цикл не є обов’язковим, але зазначення того, що подання є „основною проблемою”, а неправильне (жирним шрифтом жирним шрифтом) видається мені безрезультатним і відвертає від вказівки на практичні міркування щодо використання.
Chris Kessel

Я категорично не згоден. Міркування щодо життєвого циклу не можуть бути "основним мотиватором того, чи будете ви складати чи агрегувати", оскільки вони у вас є у багатьох випадках асоціацій незалежно від того, якщо вони представляють будь-яку часткову цілісність (агрегацію чи композицію). Кожного разу, коли асоціація має кінець із кратністю нижньої межі, більшою за 0, що відповідає обов’язковій властивості посилання, ви отримуєте залежність життєвого циклу.
Герд Вагнер,

9

З точки зору коду, склад зазвичай передбачає, що об'єкт, що містить, відповідає за створення екземплярів компонента *, а вміщуючий об'єкт містить єдині довгоживучі посилання на нього. Отже, якщо батьківський об’єкт буде знятий з посилань та зібраний сміття, це зробить і дитина.

так що цей код ...

Class Order
   private Collection<LineItem> items;
   ...
   void addOrderLine(Item sku, int quantity){
         items.add(new LineItem(sku, quantity));
   }
}

припускає, що LineItem є складовою Order - LineItems не існує поза своїм порядком, що містить. Але об’єкти Item не будуються за замовленням - вони передаються за потребою і продовжують існувати, навіть якщо магазин не має замовлень. тому вони пов'язані, а не компоненти.

* nb контейнер відповідає за інстанціювання компонента, але насправді він сам може не викликати new ... () - це Java, зазвичай перший або два фабрики потрібно пройти спочатку!


0

Концептуальні ілюстрації, наведені в інших відповідях, корисні, але я хотів би поділитися ще одним пунктом, який я знайшов корисним.

Я отримав трохи пробігу від UML для генерації коду, вихідного коду або DDL для реляційної бази даних. Там я використовував склад, щоб вказати, що таблиця містить ненульований зовнішній ключ (у базі даних) та недійсний "батьківський" (і часто "кінцевий") об'єкт у моєму коді. Я використовую агрегацію там, де я маю намір запис або об'єкт, щоб мати можливість існувати як "сирота", не приєднана до жодного батьківського об'єкта, або бути "прийнятою" іншим батьківським об'єктом.

Іншими словами, я використовував позначення композиції як скорочення, що передбачає деякі додаткові обмеження, які можуть знадобитися при написанні коду для моделі.


0

Приклад, який мені подобається: Склад: Вода є частиною ставка. (Ставок - це склад води.) Агрегація: У ставку є качки та риба (Ставок об’єднує качок та рибу)

Як бачите, я виділив напівжирним шрифтом "частина" та "має", оскільки ці 2 фрази зазвичай можуть вказувати на те, який тип зв'язку існує між класами.

Але, як вказували інші, багато разів, чи є з'єднання композицією чи агрегацією, залежить від застосування.


Але частина і має терміни, які колись бентежать. Наприклад, клас Person "має" ім'я, тому показано, як Person має зв'язок агрегування з ім'ям. Насправді це співвідношення композиції. Чому? Коли об'єкт Person знищує, також має знищуватись і ім'я. І термін "ім'я - частина людини", не звучить природно.
Асіф Шахзад

0

Настільки складно зробити різницю між сукупним відношенням та складеним відношенням, але я збираюся взяти кілька прикладів: У нас є будинок і кімнати, тут у нас складене відношення, кімната це частина будинку, і життя кімнати почалося з домашнім життям і закінчиться, коли закінчиться домашнє життя, кімната - це частина будинку, ми говоримо про склад, наприклад, країну та столицю, книгу та сторінки. Для прикладу сукупних відносин візьмемо команду та гравців, гравець може існувати без команди, а команда - це група гравців, і життя гравців може розпочатися до життя команди, якщо ми говоримо про програмування, ми можемо створити гравців, а після того, як ми створимо команду, але для композиції ні, ми створюємо кімнати всередині будинку. Композиція ----> композитна | композиція. Агрегація -------> група | елемент


0

Давайте встановимо умови. Агрегація - це метатерм у стандарті UML, і означає ОБИН композицію та спільне агрегування, просто названу спільною . Часто це називається неправильно "агрегація". Це погано, бо композиція теж є агрегацією. Як я розумію, ви маєте на увазі "спільний".

Далі від стандарту UML:

складений - вказує на те, що властивість агрегується складеним чином, тобто складений об’єкт відповідає за існування та зберігання складених об’єктів (частин).

Отже, асоціація «Університет до катедр» - це композиція, тому що кафедра не існує поза Університетом (ІМХО)

Точна семантика спільного агрегування залежить від області застосування та моделіста.

Тобто, всі інші асоціації можна скласти як спільні агрегації, якщо ви дотримуєтеся лише деяких своїх чи інших принципів. Також подивіться тут .


0

Розглянемо такі частини тіла людини, як нирки, печінка, мозок. Якщо ми спробуємо відобразити тут поняття композиції та агрегації, це буде приблизно так:

До появи трансплантації таких частин тіла, як нирки та печінка, ці дві частини тіла складали людський організм і не могли існувати ізольовано від людського тіла.

Але після появи трансплантації частин тіла їх можна пересадити в інше тіло людини, тому ці частини знаходяться в агрегації з людським тілом, оскільки їх існування в ізоляції від людського тіла можливо вже зараз.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.