Trudno mi było zrozumieć różnicę między kompozycją a agregacją w UML. Czy ktoś może mi zaproponować dobre porównanie i kontrast między nimi? Chciałbym również nauczyć się rozpoznawać różnice między nimi w kodzie i / lub zobaczyć krótki przykład oprogramowania / kodu.
Edycja: Jednym z powodów, dla których pytam, jest odwrotna dokumentacja, którą wykonujemy w pracy. Napisaliśmy kod, ale musimy wrócić i stworzyć diagramy klas dla kodu. Chcielibyśmy tylko odpowiednio uchwycić skojarzenia.
Odpowiedzi:
Rozróżnienie między agregacją a kompozycją zależy od kontekstu.
Weźmy przykład samochodu podany w innej odpowiedzi - tak, to prawda, że wydech samochodowy może stać „sam”, więc może nie być w składzie z samochodem - ale to zależy od zastosowania. Jeśli zbudujesz aplikację, która faktycznie ma do czynienia z samodzielnymi spalinami samochodowymi (aplikacja do zarządzania warsztatem samochodowym?), Wybierz agregację. Ale jeśli jest to prosta gra wyścigowa, a wydech samochodowy służy tylko jako część samochodu - cóż, kompozycja byłaby całkiem dobra.
Szachownica? Taki sam problem. Bierka szachowa nie istnieje bez szachownicy tylko w niektórych zastosowaniach. W innych (na przykład u producenta zabawek) figura szachowa z pewnością nie może zostać złożona w szachownicę.
Sytuacja się pogarsza, gdy próbujesz odwzorować kompozycję / agregację na Twój ulubiony język programowania. W niektórych językach różnica może być łatwiejsza do zauważenia („przez odniesienie” a „według wartości”, gdy sprawy są proste), ale w innych może w ogóle nie istnieć.
I ostatnia rada? Nie trać zbyt wiele czasu na ten problem. To nie jest tego warte. To rozróżnienie jest mało przydatne w praktyce (nawet jeśli masz całkowicie czytelną „kompozycję”, nadal możesz chcieć zaimplementować ją jako agregację ze względów technicznych - na przykład buforowanie).
źródło
Jako zasada:
class Person { private Heart heart; private List<Hand> hands; } class City { private List<Tree> trees; private List<Car> cars }
W kompozycji (osoba, serce, ręka) „obiekty podrzędne” (serce, ręka) zostaną zniszczone, gdy tylko osoba zostanie zniszczona.
W agregacji (miasto, drzewo, samochód) „obiekty podrzędne” (drzewo, samochód) NIE zostaną zniszczone po zniszczeniu miasta.
Najważniejsze jest to, że kompozycja kładzie nacisk na wzajemne istnienie, a łącznie ta właściwość NIE jest wymagana.
źródło
Kompozycja i agregacja to typy asocjacji. Są bardzo blisko spokrewnieni, a pod względem programowania nie wydaje się, aby między nimi istniała duża różnica. Spróbuję wyjaśnić różnicę między tymi dwoma przykładami kodu Java
Agregacja : obiekt istnieje poza drugim, jest tworzony na zewnątrz, więc jest przekazywany jako argument (na przykład) do konstruktora. Np. Ludzie - samochód. Samochód powstaje w innym kontekście, a następnie staje się własnością osoby.
// 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; } }
Kompozycja : obiekt istnieje lub ma sens tylko wewnątrz drugiego, jako część innego. Np. Ludzie - serce. Nie tworzysz serca i nie przekazujesz go innej osobie. Zamiast tego serce zostaje stworzone, gdy zostaje stworzony człowiek.
// 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”); } }
Wyjaśniono tutaj na przykładzie Różnica między agregacją a kompozycją
źródło
Kompozycja oznacza, że obiekty potomne mają wspólną długość życia z rodzicem. Agregacja nie. Na przykład szachownica składa się z kwadratów szachowych - te szachy tak naprawdę nie istnieją bez szachownicy. Jednak samochód jest zbiorem części - spaliny samochodowe są nadal spalinami samochodowymi, jeśli nie są w tym czasie częścią samochodu.
źródło
Przykładem, którego się nauczyłem, były palce u dłoni. Twoja ręka składa się z palców. Jest ich właścicielem. Jeśli dłoń umiera, umierają palce. Nie możesz „łączyć” palców. Nie możesz po prostu chwycić dodatkowych palców i dowolnie przyczepiać i odłączać je od dłoni.
Wartość tutaj, z punktu widzenia projektu, jest często związana z żywotnością obiektu, jak powiedział inny plakat. Powiedzmy, że masz klienta i on ma konto. To konto jest „skomponowanym” obiektem klienta (przynajmniej w większości kontekstów, które przychodzą mi do głowy). Jeśli usuniesz Klienta, Konto samo w sobie nie będzie miało wartości, więc również zostanie usunięte. W przypadku tworzenia obiektów często jest odwrotnie. Ponieważ Konto ma znaczenie tylko w kontekście Klienta, utworzenie Konta byłoby częścią tworzenia Klienta (lub, jeśli robisz to leniwie, byłoby to częścią jakiejś transakcji Klienta).
Przy projektowaniu warto pomyśleć o tym, które obiekty posiadają (tworzą) inne obiekty, a które tylko odwołują się (agregują) do innych obiektów. Może pomóc określić, gdzie leży odpowiedzialność za tworzenie / czyszczenie / aktualizację obiektów.
Jeśli chodzi o kod, często trudno powiedzieć. Prawie wszystko w kodzie jest odwołaniem do obiektu, więc może nie być oczywiste, czy obiekt, do którego istnieje odwołanie, jest utworzony (posiadany), czy zagregowany.
źródło
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ą
Ale jednocześnie mówią też
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:
Person
aHeart
, pokazany na poniższym diagramie. Serce zostaje zniszczone lub przeszczepione innej osobie po śmierci właściciela.Person
aBrain
.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
iCourse
, 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.
źródło
W kategoriach kodu, kompozycja zazwyczaj sugeruje, że obiekt zawierający jest odpowiedzialny za tworzenie instancji składnika *, a obiekt zawierający zawiera jedyne długotrwałe odniesienia do niego. Więc jeśli obiekt nadrzędny zostanie usunięty z odniesień i zbierany jako śmieci, to samo zrobi to dziecko.
więc ten kod ...
Class Order private Collection<LineItem> items; ... void addOrderLine(Item sku, int quantity){ items.add(new LineItem(sku, quantity)); } }
sugeruje, że element zamówienia jest składnikiem zamówienia - elementy zamówienia nie istnieją poza swoim zamówieniem. Ale obiekty Item nie są konstruowane w kolejności - są przekazywane w razie potrzeby i nadal istnieją, nawet jeśli sklep nie ma zamówień. są więc powiązane, a nie komponenty.
* nb kontener jest odpowiedzialny za instancjonowanie komponentu, ale może w rzeczywistości nie wywoływać nowego ... () samego siebie - to jest java, zwykle najpierw trzeba przejść przez jedną lub dwie fabryki!
źródło
Ilustracje koncepcyjne zawarte w innych odpowiedziach są przydatne, ale chciałbym podzielić się inną kwestią, która okazała się pomocna.
Uzyskałem pewien przebieg poza UML do generowania kodu, kodu źródłowego lub DDL dla relacyjnej bazy danych. Tam użyłem kompozycji, aby wskazać, że tabela ma w moim kodzie klucz obcy nieprzekraczający wartości null (w bazie danych) oraz obiekt „nadrzędny” (i często „końcowy”), który nie dopuszcza wartości null. Używam agregacji tam, gdzie zamierzam, aby rekord lub obiekt istniał jako „sierota”, niepowiązany z żadnym obiektem nadrzędnym lub został „adoptowany” przez inny obiekt nadrzędny.
Innymi słowy, użyłem notacji kompozycji jako skrótu, aby zasugerować dodatkowe ograniczenia, które mogą być potrzebne podczas pisania kodu dla modelu.
źródło
Przykład, który mi się podoba: Skład: Woda jest częścią stawu. (Staw jest składem wody.) Agregacja: Staw ma kaczki i ryby (Staw skupia kaczki i ryby)
Jak widać, pogrubiłem „część” i „ma”, ponieważ te 2 wyrażenia mogą zazwyczaj wskazywać, jaki rodzaj połączenia istnieje między klasami.
Ale jak podkreślają inni, często to, czy połączenie jest kompozycją, czy agregacją, zależy od aplikacji.
źródło
Tak trudno jest rozróżnić relację zagregowaną i złożoną, ale wezmę kilka przykładów, mamy dom i pokoje, tutaj mamy związek złożony, pokój jest częścią domu i życie w pokoju się zaczęło z życiem domowym i zakończeniem życia domu, gdy życie domu dobiegnie końca, pokój jest częścią domu, mówimy o kompozycji, jak kraj i stolica, książka i strony. Dla przykładu zagregowanych relacji, weźmy zespół i graczy, gracz może istnieć bez zespołu, a zespół to grupa graczy, a życie gracza może rozpocząć się przed życiem zespołowym, jeśli mówimy o programowaniu, możemy tworzyć graczy i po tym, jak stworzymy zespół, ale dla kompozycji nie, tworzymy pomieszczenia wewnątrz domu. Kompozycja ----> kompozyt | komponowanie. Agregacja -------> grupa | element
źródło
Ustalmy warunki. Agregacja jest metatermem w standardzie UML i oznacza ZARÓWNO kompozycję, jak i wspólną agregację, nazywaną po prostu współużytkowaną . Często nazywa się to niepoprawnie „agregacją”. To ZŁE, bo kompozycja też jest agregacją. Jak rozumiem, masz na myśli „udostępniony”.
Dalej od standardu UML:
Tak więc stowarzyszenie University to cathedras jest kompozycją, ponieważ katedra nie istnieje poza uniwersytetem (IMHO)
Oznacza to, że wszystkie inne skojarzenia można narysować jako wspólne agregacje, jeśli przestrzegasz tylko niektórych zasad własnych lub kogoś innego. Zajrzyj też tutaj .
źródło
Weź pod uwagę części ludzkiego ciała, takie jak nerki, wątroba, mózg. Gdybyśmy spróbowali odwzorować tutaj pojęcie kompozycji i agregacji, wyglądałoby to tak:
Przed pojawieniem się przeszczepów części ciała, takich jak nerki i wątroba, te dwie części ciała były w kompozycji z ludzkim ciałem i nie mogą istnieć w izolacji z ludzkim ciałem.
Ale po pojawieniu się przeszczepu części ciała można je przeszczepić do innego ludzkiego ciała, więc te części są agregowane z ludzkim ciałem, ponieważ ich istnienie w izolacji z ludzkim ciałem jest teraz możliwe.
źródło