To zdumiewające, jak wiele nieporozumień istnieje w kwestii rozróżnienia między częścią-całością - koncepcjami skojarzeń , agregacją i kompozycją . Głównym problemem jest powszechne nieporozumienie (nawet wśród doświadczonych programistów i autorów UML), że pojęcie kompozycji zakłada zależność cyklu życia między całością a jej częściami, tak że części nie mogą istnieć bez całości. Jednak pogląd ten pomija fakt, że istnieją również przypadki skojarzeń części-całości z częściami niepodlegającymi współużytkowaniu, w których części można oddzielić od całości i przetrwać zniszczenie.
W dokumencie specyfikacji UML definicja terminu „skład” zawsze implikowała części, których nie można udostępniać, ale nie było jasne, co jest definiującą cechą „składu”, a co jest jedynie cechą opcjonalną. Nawet w nowej wersji (z 2015 r.), UML 2.5, po próbie udoskonalenia definicji terminu „skład”, pozostaje on nadal niejednoznaczny i nie dostarcza żadnych wskazówek, jak modelować skojarzenia części całości z części wspólne, w przypadku których części można odłączyć i przetrwać zniszczenie całości, w przeciwieństwie do przypadku, gdy części nie można odłączyć i są one niszczone razem z całością. Mówią
Jeśli obiekt złożony zostanie usunięty, wszystkie wystąpienia jego części, które są obiektami, zostaną usunięte wraz z nim.
Ale jednocześnie mówią też
Obiekt części może zostać usunięty z obiektu złożonego przed usunięciem obiektu złożonego, a zatem nie może zostać usunięty jako część obiektu złożonego.
To zamieszanie wskazuje na niekompletność definicji UML, która nie uwzględnia zależności cyklu życia między komponentami i kompozytami. Dlatego ważne jest, aby zrozumieć, w jaki sposób można ulepszyć definicję UML, wprowadzając stereotyp UML dla kompozycji „ nierozłącznych”, w których komponentów nie można odłączyć od ich kompozytu, a zatem należy je zniszczyć za każdym razem, gdy ich kompozyt zostanie zniszczony.
1) Skład
Jak wyjaśnił Martin Fowler , głównym problemem charakteryzującym kompozycję jest to, że „przedmiot może być tylko częścią jednej relacji kompozycji”. Jest to również wyjaśnione w doskonałym wpisie na blogu UML Composition vs Aggregation vs Association autorstwa Geerta Bellekensa. Oprócz tej definiującej cechy kompozycji (posiadającej wyłączne lub niepodlegające współużytkowaniu części), kompozycja może również charakteryzować się zależnością cyklu życia między kompozytem a jego składnikami. W rzeczywistości istnieją dwa rodzaje takich zależności:
- Ilekroć składnik musi być zawsze dołączony do kompozytu lub, innymi słowy, gdy ma obowiązkowy kompozyt , co wyraża się liczbą „dokładnie jednej” po stronie kompozytu na linii składu, wówczas należy go użyć ponownie w (lub ponownie dołączony) do innego kompozytu lub zniszczony, gdy obecny kompozyt zostanie zniszczony. Ilustruje to skład pomiędzy
Person
a Heart
, pokazany na poniższym diagramie. Serce zostaje zniszczone lub przeszczepione innej osobie po śmierci właściciela.
- Zawsze, gdy komponentu nie można odłączyć od swojego kompozytu, czyli innymi słowy, gdy jest nierozłączny , wtedy i tylko wtedy komponent musi zostać zniszczony, gdy jego kompozyt zostanie zniszczony. Przykładem takiej kompozycji z nierozłącznymi częściami jest kompozycja między
Person
a Brain
.
Podsumowując, zależności cyklu życia mają zastosowanie tylko do określonych przypadków składu, ale nie ogólnie, dlatego nie są cechą definiującą.
Zgodnie ze specyfikacją UML: „Część może zostać usunięta z wystąpienia złożonego przed usunięciem wystąpienia złożonego, a zatem nie może zostać usunięta jako część wystąpienia złożonego”. W przykładzie a Car
- Engine
kompozycji, jak pokazano na poniższym schemacie, wyraźnie widać, że silnik można odłączyć od samochodu przed zniszczeniem samochodu, w którym to przypadku silnik nie ulega zniszczeniu i można go ponownie użyć. Jest to implikowane przez zerową lub jedną krotność po stronie złożonej linii składu.
Wielość zakończenia asocjacji kompozycja jest w złożonej strony jest 1 lub 0..1, w zależności od tego, czy elementy mają obowiązek kompozytu (musi być przymocowana do kompozytowe), czy nie. Jeśli komponenty są nierozłączne , oznacza to, że mają obowiązkowy kompozyt.
2) Agregacja
Agregacja to kolejna szczególna forma skojarzenia z zamierzonym znaczeniem relacji część-całość, w której części całości można dzielić z innymi całościami. Na przykład możemy modelować agregację między zajęciami DegreeProgram
i Course
, jak pokazano na poniższym schemacie, ponieważ kurs jest częścią programu studiów i kurs może być dzielony między dwa lub więcej programów studiów (np. Stopień inżyniera może mieć wspólną literę C kurs programowania ze stopniem informatyki).
Jednak koncepcja agregacji z częściami, które można udostępniać, nie ma wielkiego znaczenia, więc nie ma to żadnego wpływu na implementację i dlatego wielu programistów woli nie używać białego diamentu w swoich diagramach klas, ale po prostu modelować proste skojarzenie zamiast. Specyfikacja UML mówi: „Precyzyjna semantyka współdzielonej agregacji różni się w zależności od obszaru aplikacji i projektanta”.
Wielość od końca stowarzyszenia agregacji jest na całej stronie może być dowolna liczba (*), ponieważ część może należeć do lub dzielone między dowolną liczbę całości.