Чим відрізняється асоціація, агрегація та склад?


389

Чим відрізняється асоціація, агрегація та склад? Будь ласка, поясніть з точки зору реалізації.


2
Це може бути непосильним для початківців, але прогуляйтеся по специфіці надбудови UML 2: omg.org/docs/formal/09-02-02.pdf Розділ 7.3.3 для Асоціації
курінабісбіскут

6
Я також повинен додати, що в UML 2 немає такого елемента, як агрегація чи склад (хоча це було в UML 1.4). У UML 2 агрегація / композиції реалізуються як елементи асоціації із властивістю AggregationKind, встановленим як Shared, так і Composite.
курячий бісквіт

Багато відповідей на SO вже: stackoverflow.com/search?q=aggregation+and+composition
Лотара

2
корисна стаття тут codeproject.com/Articles/22769/…
GibboK

6
Я знаю, що на це вже відповіли багато разів, але я вважаю, що найкраще пояснення, яке я читав з цього питання, це саме таке: holub.com/goodies/uml/#composition
WLin

Відповіді:


384

Для двох об'єктів, 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; 
    }
}

3
Здається, C # / код Java. У цьому випадку і асоціація, і код агрегації однакові. В обох випадках на "бар" є лише посилання і Barоб'єкт може жити далі.
Аджай

@ Джеф Фостер: У мене є сумніви. Якщо я інстанціюю об'єкт бару в Baz (Bar bar) {bar = new Bar (); } у першому випадку. Чи все-таки це буде асоціація чи вона зараз стане складом?
Сакет

21
@Ajay: Агрегація зберігає посилання на об'єкти, що не стосується асоціації. Звідси різниця в реалізації.
ABCD

17
Асоціація трохи сильніше, ніж просто використання в якості параметра методу. Я вважаю, що фрагмент коду вашої асоціації більше відповідає відношенню до залежності . ви можете перевірити статтю про Мартіна Фаулера
Ахмад Абдельгані

5
@AhmadAbdelghany вірно. Перший приклад - залежність залежності. Третя працює на об'єднання та об'єднання.
Андре Валенті

122

Я знаю, що це питання позначено як C #, але такі поняття є досить загальними питаннями, як це перенаправлення тут. Тому я збираюся викласти свою точку зору тут (трохи упереджено з точки зору Java, де мені зручніше).

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

Агрегація та Склад - це підмножини асоціацій, тобто вони є конкретними випадками асоціації.

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

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

Плутати?

Приклад складу : Розгляньте приклад автомобіля та двигуна, який є дуже специфічним для цього автомобіля (тобто його не можна використовувати в будь-якому іншому автомобілі). Цей тип відносин між Автомобілем та класом SpecificEngine називається складом. Об'єкт класу Car не може існувати без об'єкта Class SpecificEngine, а об'єкт SpecificEngine не має значення без класу Car. Простіше кажучи, клас автомобілів виключно "володіє" класом SpecificEngine.

Приклад агрегації : Розглянемо тепер Автомобіль та Клас колеса . Для роботи автомобіля потрібен об'єкт Wheel. Значення об'єкта "Автомобіль" належить об'єкту "Колесо", але ми не можемо сказати, що об'єкт "Колесо" не має значення без "Об'єкта автомобіля". Він дуже добре може бути використаний на велосипеді, вантажівці чи інших автомобілях.

Підбиваючи підсумки -

Підсумовуючи це, асоціація - це дуже узагальнений термін, який використовується для представлення, коли клас використовує функції, що надаються іншим класом. Ми говоримо, що це склад, якщо одному об’єкту батьківського класу належить інший об'єкт дочірнього класу, і цей дочірній об’єкт класу не може значимо існувати без об'єкта батьківського класу. Якщо це можливо, це називається агрегацією.

Детальніше тут. Я є автором http://opensourceforgeeks.blogspot.in та додав посилання вище до відповідної публікації для отримання додаткового контексту.


8
Я збирався запитати, чому ви піклувались відповісти на вже відповів на запитання, яке було задано більше 5 років тому, але потім я прочитав ваш запис у блозі, і це було набагато інформативніше, ніж деякі відповіді тут. Оголошено!
Донбхупі

2
Я згоден з @Donbhupi, ваша відповідь є набагато більш інформативною та правильною, ніж багато інших
zish

1
Це дуже смішно, коли розробники C # та Java стверджують, що вони використовують композицію, коли вона існує лише на примітивних типах із цими мовами. Якщо ви хочете по-справжньому зрозуміти склад, ви повинні використовувати C ++, де об’єкти дійсно можуть бути частиною інших об'єктів .. Не просто плаваючі в купі пам’яті і тримають покажчики один на одного і стверджують, що є композиція ..
Кожен

@ Кожен я прийшов до того ж висновку, що і ти, але я не дуже впевнений у цьому. Наприклад, скажіть, що у мене є один клас, який семантично належить одному конкретному класу, однак об'єкт, що належить, є сміттям, зібраним після того, як його власник вже видалив сміттєзбірник, чи вважається він складом?
Пауло Андре Хаакке

Чи можемо ми мати склад у коді AC # за допомогою керованої пам'яті?
Пауло Андре Хаакке

85

Асоціація - це узагальнена концепція відносин. Вона включає як склад, так і агрегацію.

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

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

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

Trick пам'ятати різницю: є A - A ggregation і O WN - C O mpositoin

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

Тепер перегляньмо наступне зображення

відносини

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

Аналогія:

Склад : Наступна картина - це композиція зображень, тобто використання окремих зображень для створення одного зображення.
введіть тут опис зображення

Агрегація : колекція зображень в одному місці

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

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


14
Прочитавши стільки на цю тему, ця відповідь є найбільш інтуїтивно зрозумілою. Слід ставити на wikipedia.
Jankapunkt

1
Красиво сформульована.
Сід

Щодо агрегування, ви кажете "Дочірні об'єкти належать до одного батька". Це неправильно. Дійсно UML має спільну агрегацію, тобто дитина належить до кількох батьків. Ви визнаєте це у своєму прикладі про кафедру як сукупність професорів, тому що ви говорите, що професор може працювати на більш ніж одній кафедрі.
www.admiraalit.nl

@ www.admiraalit.nl Спільне згуртування AFAIK не означає, що "дитина належить до декількох батьків", це просто навпаки, кілька дітей належать до тих самих батьків. І це некомпонентна агрегація, тому що навіть якщо батьки помирають, діти можуть вижити довше.
адерхокс

65

Залежність (посилання)
Це означає, що між двома об'єктами немає концептуальної зв'язку. наприклад, посилання на об'єкти EnrollmentService на об'єкти Student & Course (як параметри методу або типи повернення)

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

Асоціація (має-а)
Це означає, що майже завжди існує зв'язок між об'єктами (вони пов'язані). Об'єкт замовлення має об’єкт Замовника

public class Order {
    private Customer customer
}

Агрегація (має-з + цілу частину)
Особливий вид об’єднання, коли між двома об’єктами існує відношення цілої частини. вони можуть жити один без одного.

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

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

Склад (має + цілу частину + право власності)
Особливий вид агрегації. А Apartmentскладається з деяких Rooms. Не Roomможе існувати без Apartment. при видаленні квартири видаляються і всі пов'язані кімнати.

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

1
Так, єдиною складною частиною у визначенні об'єктних відносин є розмежування асоціації та агрегації. Все інше зрозуміло. +1 від мене
Фуад Букредін

28

З допису Роберта Мартіна в 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
};

1
Скільки повноважень має це визначення? Чи підтримується це авторами стандарту UML? Я це підтримував інструментами?
reinierpost

1
Це Роберт К. Мартін. Цього мені достатньо авторитету :-)
Геліак

21

Як говорили інші, асоціація - це зв'язок між об'єктами, агрегація та композиція - це типи об'єднання.

З точки зору реалізації, агрегацію отримують, маючи члена класу за посиланням . Наприклад, якщо клас A агрегує об'єкт класу B, у вас буде щось подібне (в C ++):

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

Семантика агрегації полягає в тому, що коли об'єкт A знищений, B об'єкт, який він зберігає, все ще буде існувати. Під час використання композиції у вас міцніші стосунки, як правило, зберігаючи член за значенням :

class A {
    B element;
};

Тут, коли A об'єкт знищений, B об'єкт, який він містить, також буде знищений. Найпростіший спосіб досягти цього - збереження члена за значенням, але ви також можете скористатися деяким розумним вказівником або видалити член у деструкторі:

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

class A {
    B * element;

    ~A() {
        delete B;
    }
};

Важливим моментом є те, що в композиції об'єкт контейнера володіє вміщеним, тоді як в сукупності він посилається на нього.


8
Це має бути єдиною прийнятою відповіддю. Композиції не існує в C # та Java, за винятком примітивних типів ... Але ви бачите розробників цих мов, що "пояснюють" склад. Композиція означає, що об’єкт існує ВНІШЕ інший. У Java і C # ви навіть не можете це зробити, все на купі, і ви просто тримаєте покажчик на це, це дійсно агрегація, а не склад. C ++ забезпечує композицію ..
Усі

14

Дивовижно, наскільки існує сум'яття щодо розмежування об'єднань , об'єднання та складу трьох концепцій взаємозв'язку .

Зауважте, що терміни агрегації та складу використовувались у спільноті C ++, ймовірно, за певний час, перш ніж вони були визначені як особливі випадки асоціації у діаграмах класів UML.

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

Наскільки я бачу, ця плутанина має два коріння:

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

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

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

Дивіться також мою розширену відповідь на запитання щодо ПП у квітні 2009 р., Перелічені нижче.

І властивість, яка передбачалася визначати "склад" між об'єктами OOP у спільноті 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 - асоціація або агрегація (прості фрагменти коду)


подати заявку на неповний перелік неодноразово заданих питань.
Жакко

13

Асоціація

Асоціація представляє взаємозв'язок між двома класами. Вона може бути односпрямованою (в одну сторону) або двосторонній (двосторонній)

наприклад:

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

Клієнт розміщує замовлення

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

А одружений на Б

Б одружений на А

Агрегація

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

наприклад:

клуб має членів

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

Склад

Це сильніша форма агрегації. "Цілий" відповідає за створення або знищення його "частин".

Наприклад:

У школі є відділи

У цьому випадку школа ("ціла") повинна була померти, відділ ("частини") загине разом із нею. Тому що кожна частина може належати лише одному «цілому».


У разі узгодження. Якщо я повинен використовувати його class Club(){ _member = new Member } або передати його як посиланняclass Club(){ addMember(Member member) { this._member = member } }
ролик

12

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

Асоціація

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

Слабка асоціація

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



Хороша відповідь. 1) Запитання до прикладу композиції: Ленг та Рука (композиція) Особа. якщо я створю клас "Тварини і сон", то людина "Сон" (узгодження); Сон (узгодження) тварина. Це правильно? 2). Склад руки Особа : class Person() { private hand = new Hand }. Особа, що class Person() { private sleep = new Sleep }відповідає режиму сну, чи дійсно використовується ключ "новий" у режимі сну? або я повинен передати це як довідник, оскільки це узгодження? class Person() { private Sleep _sleep; public addSleep(Sleep sleep) { this._sleep = sleep} }
ролик

7

Склад (Якщо ви видалите "ціле", "частина" також видаляється автоматично - "Власність")

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

  • Зазвичай використовують звичайні змінні члена.

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

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

Склад у С ++

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

Хто відповів, проголосував за цю відповідь. Чи можете ви пояснити причину відмови від її голосування?
Саурабх Раоот

Що мене дійсно бентежить, це те, що у багатьох випадках справа не у власнику власника, а в тому, що він володіє, "утримує" власника. Наприклад, автомобіль не має вказівника типу Engine *, але клас Engine має член типу "Автомобіль" для зберігання автомобіля, який йому належить. Я не дуже його розумію, особливо стосунки розуму класів у цьому випадку.
дуду

6

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

Я бачу на основі коротких ознайомлень з багатьма публікаціями про SO та деяких документах UML, що існують 4 основні конкретні форми асоціації класів:

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

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

Я здогадуюсь, що "родова асоціація" має використовуватися в основному за двох обставин:

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

1
Як саме ви реалізували б загальну асоціацію, якщо всі інші варіанти будуть виключені? Якщо A не складається з B (значення B знаходиться в A), A не є агрегацією B (посилання B не в A), B не успадковується / не реалізується від A, а B не використовується як повернення, параметр або в межах використання функції A, ви майже не залишаєте жодного відношення.
Дін P

1
@DeanP Наразі він може бути загальним, а пізніше буде перетворений на один із 4 (тоді він стане реалізованим); АБО це може бути стосунок, який не відповідає 4 типу, скажімо, ви хочете асоціації, що означає "схоже", без родової асоціації ви змушені будете використовувати один із 4, таким чином вводячи в оману читача, тоді як якщо ви використовуєте загальне, ви, ймовірно, анотуватимете це або помістите примітку, що пояснює, що це таке, і більшість людей читають нотатки лише тоді, коли вони не розуміють символ;)
Олівер

5

Я думаю, що це посилання стане вашим домашнім завданням: http://ootips.org/uml-hasa.html

Для розуміння термінів я пам’ятаю приклад у перші дні програмування:

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

Якщо у вас є "квадратний" об'єкт, у якого "кольоровий" об'єкт, і квадрат видаляється, об'єкт "колір" все ще може існувати, тобто агрегація

Вони обоє є асоціаціями , головна відмінність - концептуальна


5

Склад : Це коли ви знищуєте об'єкт (школу), інший об'єкт (класні кімнати), який пов'язаний з ним, теж буде знищений. Обидва вони не можуть існувати самостійно.

Агрегація : Це в точності протилежне вищевказаній ( Composition) асоціації, коли одного разу ви вбиваєте об'єкт ( Company), інший об'єкт ( Employees), який пов'язаний з ним, може існувати самостійно.

Асоціація .
Склад та агрегація - це дві форми об'єднання.


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

1
так, абсолютно. Погоджуєтесь ... +1 Дякую @AlexPopov за те, що він це вказав. :)
Куласангар

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

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

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

3

У дуже простому реченні:
Агрегація та Склад - це підмножини асоціації.

  • A використовує B -> це агрегація

  • А потребує В -> - це композиція.

Детальніше читайте тут .


2

Я хотів би проілюструвати, як три терміни реалізовані в Rails. ActiveRecord називає будь-який тип відносин між двома моделями та an 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

2

Від: Ремо Х. Янсен, книга «Початок реагування: Навчання TypeScript 2.x - друге видання»:

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

Ми називаємо агрегацію тими відносинами, об'єкти яких мають незалежний життєвий цикл, але існує право власності, і дочірні об'єкти не можуть належати до іншого батьківського об'єкта. Візьмемо приклад мобільного телефону та акумулятора стільникового телефону. Один акумулятор може належати до телефону, але якщо телефон перестане працювати, і ми видалимо його з нашої бази даних, акумулятор телефону не буде видалений, оскільки він все ще може бути функціональним. Так, у сукупності, поки існує право власності, об’єкти мають свій життєвий цикл

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


1

Асоціація - це відносини між двома окремими класами, і асоціація може бути будь-якого типу, наприклад, один до одного, один до травня і т.д.

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

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


1

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

Склад: це відносини "частково".

наприклад "двигун є частиною автомобіля", "серце - частина кузова".

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

Асоціація: це відносини типу "має"

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

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

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

Агрегація: заснована на стосунках "має-має", і це \\ особлива форма об'єднання

наприклад, "Студент" та "адреса". Кожен студент повинен мати адресу, так що зв'язок між класом Студент та класом Адреса буде співвідношенням типу "Has-A", але навпаки не відповідає дійсності.

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

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