Позначення діаграми класів UML: Відмінності між асоціацією, агрегацією та складом


39

Мене плутають деякі позначення діаграм класів UML.

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

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

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

Два визначення позначення агрегації :

Визначення 1: Позначення агрегації між двома класами підходить кожного разу, коли екземпляр класу A містить колекцію екземплярів класу B (наприклад, Список, масив тощо).

Визначення 2: Посилання агрегації між двома класами підходить, якщо екземпляр класу A містить посилання на екземпляр класу B, а екземпляр B залежить від життєвого циклу екземпляра. Значення: Коли екземпляр класу A буде видалений, такий буде і екземпляр класу B. Екземпляр класу B повністю міститься в екземплярі класу A, на відміну від екземпляра класу A, просто володіє посиланням на екземпляр клас В (який є регулярною асоціацією).

Що стосується того, що означає нотація Складу та чим вона відрізняється від позначення Агрегації, я не впевнений.

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


Визначення 2 звучить більше як визначення для складу, а не для агрегації. Визначення 1 звучить цілком правильно.
jbx

Відповіді:


32

Три ланки асоціації, агрегації та складу утворюють своєрідну шкалу щодо того, наскільки тісно два класи пов'язані один з одним.

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

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

Співвідношення Агрегації знаходиться десь між цими двома кінцями, але, здається, ніхто не погоджується, де саме, тому також немає загально узгодженого визначення того, що означає Агрегація. У цьому сенсі обидва визначення, які ви знайшли, є правильними, і якщо ви запитаєте 10 людей, ви ризикуєте отримати 11 різних визначень.


1
Дякую за вашу відповідь. Ось як я розумію речі, будь ласка, скажіть, чи це розумне визначення. 1- Асоціація - це коли об'єкт A повинен знати про об'єкт B, щоб виконувати його функціональність. 2- І Агрегація, і Склад визначають відносини "власності" - екземпляр класу A концептуально володіє екземпляром класу B. Але термін служби екземпляра B не залежить від часу існування екземпляра. Наприклад, відділ із працівниками. Відділ "володіє" екземпляром працівника, але він продовжує жити без відділу. Склад як Агрегація, але
Aviv Cohn

1
термін служби екземпляра B залежить від терміну експлуатації. Більш міцні відносини "власності". Наприклад: Автомобіль та колесо. Автомобіль 'повністю містить' колесо. Екземпляр Wheel не буде продовжувати жити, якщо автомобільний примірник його не містить. Це розумна диференціація?
Авів Кон

@Prog: Так, це розумне визначення. Просто пам’ятайте, що інші можуть не поділяти це визначення, і вам може знадобитися пояснити ваше використання агрегації їм.
Барт ван Інген Шенау

Що ви скажете, є найбільш поширеним визначенням для позначення агрегації? Визначення, яке я використовую? Визначення "має колекцію"? Щось ще?
Авів Кон

Посилання на стандарт OMG нижче є повчальним. Асоціація та склад досить прості. Агрегація є хиткою. На практиці я вважаю, що "частина" тесту працює добре ("власність" є неоптимальним способом думати про це). Людина може бути частиною клубу, таким чином клуб об’єднує людей (він ними не володіє). Коли клуб знищений, люди продовжують існувати.
Хуліакс

10

Композиція - це коли object Aміститься, object Bа object Aтакож відповідає за створення object B.

Композиційні відносини

У нас є клас A, який буде використовуватися класом B.

final class A
{
}

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

Склад прямої ініціалізації:

final class B
{
    private $a = new A();
}

Склад ініціалізації конструктора

final class B
{
    private $a;

    public function __construct()
    {
        $this->a = new A();
    }
}

Ледачий склад ініціалізації

final class B
{
    private $a = null;

    public function useA()
    {
        if ($this->a === null) {
            $this->a = new A();
        }

        /* Use $this->a */
    }
}

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

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

Композиція іноді має сенс, наприклад, дзвінки new DateTimeв php або new std::vector<int>в C ++. Але частіше за все це попередження про те, що дизайн вашого коду неправильний.

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

Крім того, якщо ви використовували ледачу композицію ініціалізації , що означає, що ви працюєте object Bпід назвою " useA()метод", а створення не object Aвийде, ваш object Bраптом марний.


З іншого боку, агрегація - це спосіб взаємовідносин, який слід принципу DI . object Bнеобхідно використовувати object A, то ви повинні пройти вже створений екземпляр object Aдо object B, і має створення object Aзбою, нічого буде прийнятий в першу чергу.

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

Це все Агрегації

Найсильніша, конструкторська інжекція ( object Bбез неї не існує object A)

final class B
{
    private $a;

    public function __construct(A $a)
    {
        $this->a = $a;
    }
}

Збільшена (ви можете або не можете використовувати object Aвсередині object B, але якщо це зробити, ви, ймовірно, повинні встановити її спочатку).

Через сетер:

final class B
{
    private $a;

    public function setA(A $a)
    {
        $this->a = $a;
    }
}

Через публічну власність:

final class B
{
    public $a;
}

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


1
Перегляд прикладів коду справді допомагає! Пояснення англійською мовою без коду видаються настільки розпливчастими та суб'єктивними.
Ніко Белік

1

Додатково витяг з поточного стандарту UML:

11.5.4 Асоціації - Семантика - Позначення

[...] Двійкова асоціація може мати один кінець з агрегуванням = AggregationKind :: shared або агрегація = AggregationKind :: composite. Коли один кінець має агрегації = AggregationKind :: загальний порожнистий алмаз додається в якості терміналу прикраси в кінці лінії асоціації протилежного кінця , поміченої агрегації = AggregationKind :: спільно. Алмаз повинен бути помітно меншим, ніж алмазне позначення для асоціацій. Асоціація з агрегацією = AggregationKind :: composite також має алмаз на відповідному кінці, але відрізняється тим, що алмаз заповнений . […]

9.5.4 Класифікація - Властивості - Позначення

[…] Іноді властивість використовується для моделювання обставин, коли один екземпляр використовується для групування набору екземплярів; це називається агрегацією. Щоб представити такі обставини, Властивість має властивість агрегування типу AggregationKind; примірник, що представляє всю групу, класифікується власником власності, а екземпляри, що представляють згруповані особи, класифікуються за типом власності. AggregationKind - це перерахування з такими буквальними значеннями:

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

[…]


0

Я вже опублікував відповідь на Stackoverflow .

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

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

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